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.2.1 20240805

The following thirdparty software was used in the benchmarks:

  • CasADi 3.6.6 (autodiff and NLP solver frontend)
  • Ipopt 3.14.16 (NLP solver backend)
  • MUMPS 5.7.0 (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.dev238.tar.gz (120.5 kB view details)

Uploaded Source

Built Distributions

sleipnirgroup_jormungandr-0.0.1.dev238-cp312-cp312-win_amd64.whl (468.3 kB view details)

Uploaded CPython 3.12 Windows x86-64

sleipnirgroup_jormungandr-0.0.1.dev238-cp312-cp312-manylinux_2_35_x86_64.whl (409.7 kB view details)

Uploaded CPython 3.12 manylinux: glibc 2.35+ x86-64

sleipnirgroup_jormungandr-0.0.1.dev238-cp312-cp312-macosx_10_9_universal2.whl (683.4 kB view details)

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

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

Uploaded CPython 3.11 Windows x86-64

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

Uploaded CPython 3.10 Windows x86-64

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

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

sleipnirgroup_jormungandr-0.0.1.dev238-cp39-cp39-win_amd64.whl (468.6 kB view details)

Uploaded CPython 3.9 Windows x86-64

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev238.tar.gz
Algorithm Hash digest
SHA256 9c0e7a1370a427a71e670b0adbf6b456af0886045d50c55b826bd1a11bd35df8
MD5 df4b56b2b3f7800d4f9549a26f24427a
BLAKE2b-256 f25036eacbbc7a05e9bf39e71a974ceb0ba6cc3520a7267aaf401de52156e45a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev238-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 108a6b2c24aa0d8effcad82ccece208ea8122dc9f0c71a800cd257b1a9cd8fe5
MD5 25cd4240a66efff955d73a94cbda8e6c
BLAKE2b-256 636d907132ac94b7ca3083d70d2e65011833b25a7eda681c77b284b1db3c1107

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev238-cp312-cp312-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 193cb778cc1e4ba6697f5e3ae45701b78c548ca5a2668983dee3e13f6d457a41
MD5 a5b8a5025421bd14fccaf399fbd168c5
BLAKE2b-256 ee5c74d567a285559f9626e38a9f33fd6ce2b3f60c9f6f6f80a8e6ad13df959a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev238-cp312-cp312-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 8d2d13b4fbb80b88f5d07d0e5c32844efb2dd1520eef7e11e8a6cd726730a90f
MD5 b488680720f0705c875a07c3c28329b3
BLAKE2b-256 9f00048539d2e0cc45869921d8c09a6b61e26cce552b84aff5fa078eceaf2af2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev238-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 daeb35e25ff9635e43f56affc02ca9b2b84ebfb5541fe5bca1bbb8703b6698fb
MD5 5553db5c16068d54d68a3c00c9e8f9db
BLAKE2b-256 1b70dc5ab742575d9f84bafae7838cc1fbb77b76d8e0c7d398169ba0c62555c0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev238-cp311-cp311-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 e649c56af527468ec70f5815e6cc52f470a6bfcfd4d708b0daba2466a3fea240
MD5 78f3b2264e32b30f6d3712bc457561d2
BLAKE2b-256 fc670a9ea5ffaee21bd3e77ce75ec2bf20bf60a0c46a1dc943f94ae85e35d498

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev238-cp311-cp311-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 d2a9bc332d70d1b3b7c20c326de117aa7e757db94ff8c6aa579339e7d4ceff07
MD5 2511c488561def938a78ae0c699bb6ec
BLAKE2b-256 0a3f9e01f9e69d2cbe95529340c00a76c29c7e13afd422dbbf3e9c2795f31508

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev238-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 92ede61e632b3fcf1e8d219164ea37c1170e012309b0b759e67ca8d4a88f3618
MD5 8337bb0968e831754218c4602c3e2d43
BLAKE2b-256 1068ddc7dfd8f5095c7ed1849bac280f378136976097f97ffe1bda9f1276892c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev238-cp310-cp310-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 5025588a3f16313a7c28dc6433e48a75653927c35b3ad2caaf7236f33645c197
MD5 e5f97afa7ffa62541e8619a90a66f6ee
BLAKE2b-256 b3d13f3f5179d010ae02a63ba25d7b57c70e0c51f292d901c51a5db5d4b24539

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev238-cp310-cp310-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 5c79c4250675ae9738edc63750f8c501eb876535eec932808dbc93b609c65fcf
MD5 2af79ea8f4fd0eab591fbe91481b8686
BLAKE2b-256 4d88030d055149e94340823d02869f8c6dd16ba64b3bc704aa56aaae6335f80d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev238-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 744edc53aa309a43da5321a06b9ab63a830a7484a65fec8812573dc1235e8f46
MD5 dcd9023831f48ed30f560f75d07a5de6
BLAKE2b-256 b15cbf262db5aea609b67c5ee21cedf0e908087c5a4db074b269fbf0012c4bec

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev238-cp39-cp39-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 34059ad7bf5b0fc02262545e28c54a7a165366dd749488c4d68038e6fa47172e
MD5 9102bb6d92dd27cf0b839b72c1ed83d0
BLAKE2b-256 fbebfa60efdb9a706cd34ab01cd07dba159b1cd7410be783ec9acca4b1ced7d8

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