-
Notifications
You must be signed in to change notification settings - Fork 42
Building osqp 1.x
The following build instructions illustrate how you can use the osqp git source tree to build osqp wheels that support different algebra backends.
The procedure has been tested out on Linux. The process should be identical on MacOS and Windows, though of course you will likely not be able to to build osqp-cuda wheels on MacOS, due to missing cuda-toolkit on Mac platforms.
Create a dedicated conda environment to build osqp. The osqp-python CI uses several python versions, but here we'll use python 3.9. Checkout and cd into the code.
conda create --name osqp-python-build python=3.9 pip
conda activate osqp-python-build
git clone https://github.com/osqp/osqp-python.git
cd osqp-python
python -m pip wheel . --no-deps --wheel-dir dist
The resulting wheel is available in the dist folder, and can be installed using pip install dist/osqp-1.*.whl
dist
├── osqp-1.0.0b2.dev68+gcaa6446-cp39-cp39-linux_x86_64.whl
The default wheel we built provides us with the osqp module, and we can check that we have the built-in algebra available:
python -c "from osqp import algebras_available; print(algebras_available())"
['builtin']
The process assumes that the mkl development library has been installed, and environment variables set so that the build process can discover these libraries (in particular, you will likely need to set MKL_ROOT, which on my machine is set to opt/intel/oneapi/mkl/latest). When working on a cluster, you may want to look for a module that populates the necessary environment variables (on our clusters, we do a module load intel-mkl/2024.0, for example).
If you're using a
condaenvironment to buildosqp, one way to getMKLis to try (osqpuses this in its CI):
conda install -c https://software.repos.intel.com/python/conda/ mkl-devel
On Windows:
conda install -c https://software.repos.intel.com/python/conda/ dpcpp_impl_win-64
However you decide to get MKL for your platform, the next step is to build the wrappers for the mkl backend:
python -m pip wheel backend/mkl --no-deps --wheel-dir dist
The resulting wheel is available in the dist folder, and can be installed using pip install dist/osqp_mkl-1.*.whl
dist
├── osqp-1.0.0b2.dev68+gcaa6446-cp39-cp39-linux_x86_64.whl
└── osqp_mkl-1.0.0b2.dev68+gcaa6446-cp39-cp39-linux_x86_64.whl
The mkl wheel we built provides us with the osqp_mkl module. When we try to do this:
10:45 $ python -c "import osqp_mkl"
Traceback (most recent call last):
File "<string>", line 1, in <module>
ImportError: libmkl_rt.so.2: cannot open shared object file: No such file or directory
This is because we need the mkl libraries available to python at runtime to be able to use osqp-mkl. There are many ways for users to do this, so we don't enforce an mkl dependency in pip to install the osqp_mkl wheels. An easy way to do this in conda would be conda install anaconda::mkl, for example.
Note that while its possible to do an import osqp_mkl in python, we'll never import that module directly in our code, and just use import osqp. We can check that we have the mkl algebra in osqp available:
python -c "from osqp import algebras_available; print(algebras_available())"
['mkl', 'builtin']
Note that mkl appears before builtin, and will be the preferred backend for all osqp operations. We can verify this by running:
python -c "from osqp import default_algebra; print(default_algebra())"
mkl
This behavior can be overridden by setting the OSQP_ALGEBRA_BACKEND environment variable (which can take the values builtin, mkl, or cuda).
OSQP_ALGEBRA_BACKEND=builtin python -c "from osqp import default_algebra; print(default_algebra())"
builtin
This assumes you have the cuda-toolkit installed, and available at /usr/local/cuda. When working on a cluster, you may want to look for a module that populates the necessary environment variables (on our clusters, we do a module load cudatoolkit/12.4, for example).
python -m pip wheel backend/cuda --no-deps --wheel-dir dist
The resulting wheel is available in the dist folder, and can be installed using pip install dist/osqp_cuda-1.*.whl
dist
├── osqp-1.0.0b2.dev68+gcaa6446-cp39-cp39-linux_x86_64.whl
├── osqp_cuda-1.0.0b2.dev68+gcaa6446-cp39-cp39-linux_x86_64.whl
└── osqp_mkl-1.0.0b2.dev68+gcaa6446-cp39-cp39-linux_x86_64.whl
The cuda wheel we built provides us with the osqp_cuda module, and we can check that we have the cuda algebra available:
python -c "from osqp import algebras_available; print(algebras_available())"
['cuda', 'mkl', 'builtin']
Again, the default algebra can be overridden with the OSQP_ALGEBRA_BACKEND environment variable.
Finally, to test that osqp is installed/working correct with all available algebras, run the tests.
pip install .[dev]
pytest
The tests run across all available algebras. The OSQP_ALGEBRA_BACKEND environment variable does not need to be set, and has no effect for the tests. If the mkl backend is available, then the tests are run for both the "direct" and "indirect" modes of mkl.
To pick exactly what algebras are tested, read on.
Tests that use the mkl backend and the indirect mode are slow to run on head nodes of clusters, where cpu cores are a shared resource and thus cannot be monopolized. Tests involving the cuda algebra may not be possible to run on head nodes of clusters anyway (because of lack of GPUs there). Also, codegen tests in osqp require an internet connection to work properly, which compute nodes may or may not have (because the generated code gets compiled using python+cmake, which wants to fetch certain modules..)
For these and other unforeseen scenarios, fine-tuning of test parametrization is supported using the OSQP_TEST_ALGEBRA_INCLUDE and OSQP_TEST_ALGEBRA_SKIP environment variables (both optional). These variables can take space-delimited values that include builtin, mkl-direct, mkl-indirect, and cuda. Of course, this can be combined with the -k pattern selection that pytest itself supports.
For example:
-
Run all tests for all available algebras:
pytest -
Run all tests, but only for the
builtinandmkl-directalgebras (if available):OSQP_TEST_ALGEBRA_INCLUDE="builtin mkl-direct" pytest -
Run all tests, but skip the
cudaalgebra:OSQP_TEST_ALGEBRA_SKIP="cuda" pytest -
Run all tests, but only for the
builtinalgebra, and skip thecodegentests:OSQP_TEST_ALGEBRA_INCLUDE="builtin" pytest -k "not codegen"