Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build_cuda_windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ jobs:
del %TEMP%\cuda.exe

- name: Build wheels
uses: pypa/cibuildwheel@v2.23
uses: pypa/cibuildwheel@v3.3.1
with:
package-dir: backend/cuda
config-file: backend/cuda/cibuildwheel.toml
Expand Down
2 changes: 1 addition & 1 deletion backend/cuda/cibuildwheel.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.cibuildwheel]
build = "cp3*"
skip = ["cp313t-*", "cp314t-*", "*-win32", "*-manylinux_i686", "*-musllinux_*"]
skip = ["cp314t-win_amd64", "*-win32", "*-manylinux_i686", "*-musllinux_*"]
build-verbosity = 1
before-build = "rm -rf {package}/osqp_sources/build"
repair-wheel-command = ""
Expand Down
4 changes: 2 additions & 2 deletions backend/mkl/cibuildwheel.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.cibuildwheel]
build = "cp3*"
skip = ["cp313t-*", "cp314t-*", "*-win32", "*-manylinux_i686", "*-musllinux_*"]
skip = ["cp314t-win_amd64", "*-win32", "*-manylinux_i686", "*-musllinux_*"]
build-verbosity = 1
before-build = "rm -rf {package}/osqp_sources/build"

Expand All @@ -19,7 +19,7 @@ before-all = [
"wget -q https://registrationcenter-download.intel.com/akdlm/IRC_NAS/cd013e6c-49c4-488b-8b86-25df6693a9b7/m_BaseKit_p_2023.2.0.49398.dmg",
"hdiutil attach -noverify -noautofsck m_BaseKit_p_2023.2.0.49398.dmg",
"sudo /Volumes/m_BaseKit_p_2023.2.0.49398/bootstrapper.app/Contents/MacOS/bootstrapper --silent --eula accept --components intel.oneapi.mac.mkl.devel",
"pip install 'cmake==3.18.4'"
"pip install cmake"
]
environment = { MKL_ROOT = "/opt/intel/oneapi/mkl/latest" }
repair-wheel-command = ""
Expand Down
10 changes: 9 additions & 1 deletion cibuildwheel.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.cibuildwheel]
build = "cp3*"
skip = ["cp313t-*", "cp314t-*", "*-win32", "*-manylinux_i686", "*-musllinux_*"]
skip = ["cp314t-win_amd64", "*-win32", "*-manylinux_i686", "*-musllinux_*"]
build-verbosity = 1
before-build = "rm -rf {package}/osqp_sources/build"
# Install CPU-only version of torch beforehand since that allows cibuildwheel
Expand All @@ -18,6 +18,14 @@ before-test = 'pip install scipy --prefer-binary'
test-groups = ["test-no-nn"]
test-command = "python -m pytest -s {project}/src/osqp/tests --continue-on-collection-errors --ignore={project}/src/osqp/tests/nn_test.py"

[[tool.cibuildwheel.overrides]]
# Free-threaded Python: torch support is experimental and not available
# on all platforms, so skip the nn tests.
select = "cp313t-* cp314t-*"
before-test = 'pip install scipy --prefer-binary'
test-groups = ["test-no-nn"]
test-command = "python -m pytest -s {project}/src/osqp/tests --continue-on-collection-errors --ignore={project}/src/osqp/tests/nn_test.py"

[tool.cibuildwheel.pyodide]
build = "cp312-pyodide_wasm32"
before-test = ""
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[build-system]
requires = ["scikit-build-core", "pybind11"]
requires = ["scikit-build-core", "pybind11>=2.13"]
build-backend = "scikit_build_core.build"

[project]
Expand Down
131 changes: 61 additions & 70 deletions src/bindings.cpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -176,18 +176,18 @@ OSQPInfo* PyOSQPSolver::get_info() {
}

OSQPInt PyOSQPSolver::warm_start(py::object x, py::object y) {
OSQPFloat* _x;
OSQPFloat* _y;
OSQPFloat* _x = NULL;
OSQPFloat* _y = NULL;

if (x.is_none()) {
_x = NULL;
} else {
_x = (OSQPFloat *)py::array_t<OSQPFloat>(x).data();
py::array_t<OSQPFloat> _x_arr, _y_arr;

if (!x.is_none()) {
_x_arr = py::array_t<OSQPFloat>(x);
_x = (OSQPFloat *)_x_arr.data();
}
if (y.is_none()) {
_y = NULL;
} else {
_y = (OSQPFloat *)py::array_t<OSQPFloat>(y).data();
if (!y.is_none()) {
_y_arr = py::array_t<OSQPFloat>(y);
_y = (OSQPFloat *)_y_arr.data();
}

return osqp_warm_start(this->_solver, _x, _y);
Expand All @@ -214,93 +214,83 @@ OSQPInt PyOSQPSolver::update_rho(OSQPFloat rho_new) {
}

OSQPInt PyOSQPSolver::update_data_vec(py::object q, py::object l, py::object u) {
OSQPFloat* _q;
OSQPFloat* _l;
OSQPFloat* _u;
OSQPFloat* _q = NULL;
OSQPFloat* _l = NULL;
OSQPFloat* _u = NULL;

if (q.is_none()) {
_q = NULL;
} else {
_q = (OSQPFloat *)py::array_t<OSQPFloat>(q).data();
py::array_t<OSQPFloat> _q_arr, _l_arr, _u_arr;

if (!q.is_none()) {
_q_arr = py::array_t<OSQPFloat>(q);
_q = (OSQPFloat *)_q_arr.data();
}
if (l.is_none()) {
_l = NULL;
} else {
_l = (OSQPFloat *)py::array_t<OSQPFloat>(l).data();
if (!l.is_none()) {
_l_arr = py::array_t<OSQPFloat>(l);
_l = (OSQPFloat *)_l_arr.data();
}
if (u.is_none()) {
_u = NULL;
} else {
_u = (OSQPFloat *)py::array_t<OSQPFloat>(u).data();
if (!u.is_none()) {
_u_arr = py::array_t<OSQPFloat>(u);
_u = (OSQPFloat *)_u_arr.data();
}

return osqp_update_data_vec(this->_solver, _q, _l, _u);
}

OSQPInt PyOSQPSolver::update_data_mat(py::object P_x, py::object P_i, py::object A_x, py::object A_i) {
OSQPFloat* _P_x;
OSQPInt* _P_i;
OSQPFloat* _P_x = NULL;
OSQPInt* _P_i = NULL;
OSQPInt _P_n = 0;
OSQPFloat* _A_x;
OSQPInt* _A_i;
OSQPFloat* _A_x = NULL;
OSQPInt* _A_i = NULL;
OSQPInt _A_n = 0;

if (P_x.is_none()) {
_P_x = NULL;
} else {
auto _P_x_array = py::array_t<OSQPFloat>(P_x);
_P_x = (OSQPFloat *)_P_x_array.data();
_P_n = _P_x_array.size();
py::array_t<OSQPFloat> _P_x_arr, _A_x_arr;
py::array_t<OSQPInt> _P_i_arr, _A_i_arr;

if (!P_x.is_none()) {
_P_x_arr = py::array_t<OSQPFloat>(P_x);
_P_x = (OSQPFloat *)_P_x_arr.data();
_P_n = _P_x_arr.size();
}

if (P_i.is_none()) {
_P_i = NULL;
} else {
auto _P_i_array = py::array_t<OSQPInt>(P_i);
_P_i = (OSQPInt *)_P_i_array.data();
_P_n = _P_i_array.size();
if (!P_i.is_none()) {
_P_i_arr = py::array_t<OSQPInt>(P_i);
_P_i = (OSQPInt *)_P_i_arr.data();
_P_n = _P_i_arr.size();
}

if (A_x.is_none()) {
_A_x = NULL;
} else {
auto _A_x_array = py::array_t<OSQPFloat>(A_x);
_A_x = (OSQPFloat *)_A_x_array.data();
_A_n = _A_x_array.size();
if (!A_x.is_none()) {
_A_x_arr = py::array_t<OSQPFloat>(A_x);
_A_x = (OSQPFloat *)_A_x_arr.data();
_A_n = _A_x_arr.size();
}

if (A_i.is_none()) {
_A_i = NULL;
} else {
auto _A_i_array = py::array_t<OSQPInt>(A_i);
_A_i = (OSQPInt *)_A_i_array.data();
_A_n = _A_i_array.size();
if (!A_i.is_none()) {
_A_i_arr = py::array_t<OSQPInt>(A_i);
_A_i = (OSQPInt *)_A_i_arr.data();
_A_n = _A_i_arr.size();
}

return osqp_update_data_mat(this->_solver, _P_x, _P_i, _P_n, _A_x, _A_i, _A_n);
}

OSQPInt PyOSQPSolver::adjoint_derivative_compute(const py::object dx, const py::object dy) {
OSQPFloat* _dx;
OSQPFloat* _dy;
OSQPFloat* _dx = NULL;
OSQPFloat* _dy = NULL;

if (dx.is_none()) {
_dx = NULL;
} else {
auto _dx_array = py::array_t<OSQPFloat>(dx);
_dx = (OSQPFloat *)_dx_array.data();
}
py::array_t<OSQPFloat> _dx_arr, _dy_arr;

if (dy.is_none()) {
_dy = NULL;
} else {
auto _dy_array = py::array_t<OSQPFloat>(dy);
_dy = (OSQPFloat *)_dy_array.data();
if (!dx.is_none()) {
_dx_arr = py::array_t<OSQPFloat>(dx);
_dx = (OSQPFloat *)_dx_arr.data();
}

if (!dy.is_none()) {
_dy_arr = py::array_t<OSQPFloat>(dy);
_dy = (OSQPFloat *)_dy_arr.data();
}

return osqp_adjoint_derivative_compute(this->_solver, _dx, _dy);

}

OSQPInt PyOSQPSolver::adjoint_derivative_get_mat(CSC& dP, CSC& dA) {
Expand All @@ -311,9 +301,10 @@ OSQPInt PyOSQPSolver::adjoint_derivative_get_mat(CSC& dP, CSC& dA) {
}

OSQPInt PyOSQPSolver::adjoint_derivative_get_vec(py::object dq, py::object dl, py::object du) {
OSQPFloat* _dq = (OSQPFloat *)py::array_t<OSQPFloat>(dq).data();
OSQPFloat* _dl = (OSQPFloat *)py::array_t<OSQPFloat>(dl).data();
OSQPFloat* _du = (OSQPFloat *)py::array_t<OSQPFloat>(du).data();
py::array_t<OSQPFloat> _dq_arr(dq), _dl_arr(dl), _du_arr(du);
OSQPFloat* _dq = (OSQPFloat *)_dq_arr.data();
OSQPFloat* _dl = (OSQPFloat *)_dl_arr.data();
OSQPFloat* _du = (OSQPFloat *)_du_arr.data();

return osqp_adjoint_derivative_get_vec(this->_solver, _dq, _dl, _du);
}
Expand Down
82 changes: 38 additions & 44 deletions src/osqp/codegen/pywrapper/bindings.cpp.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -28,68 +28,62 @@ py::tuple solve() {
}

OSQPInt update_data_vec(py::object q, py::object l, py::object u) {
OSQPFloat* _q;
OSQPFloat* _l;
OSQPFloat* _u;

if (q.is_none()) {
_q = NULL;
} else {
_q = (OSQPFloat *)py::array_t<OSQPFloat>(q).data();
OSQPFloat* _q = NULL;
OSQPFloat* _l = NULL;
OSQPFloat* _u = NULL;

py::array_t<OSQPFloat> _q_arr, _l_arr, _u_arr;

if (!q.is_none()) {
_q_arr = py::array_t<OSQPFloat>(q);
_q = (OSQPFloat *)_q_arr.data();
}
if (l.is_none()) {
_l = NULL;
} else {
_l = (OSQPFloat *)py::array_t<OSQPFloat>(l).data();
if (!l.is_none()) {
_l_arr = py::array_t<OSQPFloat>(l);
_l = (OSQPFloat *)_l_arr.data();
}
if (u.is_none()) {
_u = NULL;
} else {
_u = (OSQPFloat *)py::array_t<OSQPFloat>(u).data();
if (!u.is_none()) {
_u_arr = py::array_t<OSQPFloat>(u);
_u = (OSQPFloat *)_u_arr.data();
}

return osqp_update_data_vec(&{{prefix}}solver, _q, _l, _u);
}

#if OSQP_EMBEDDED_MODE == 2
OSQPInt update_data_mat(py::object P_x, py::object P_i, py::object A_x, py::object A_i) {
OSQPFloat* _P_x;
OSQPInt* _P_i;
OSQPFloat* _P_x = NULL;
OSQPInt* _P_i = NULL;
OSQPInt _P_n = 0;
OSQPFloat* _A_x;
OSQPInt* _A_i;
OSQPFloat* _A_x = NULL;
OSQPInt* _A_i = NULL;
OSQPInt _A_n = 0;

if (P_x.is_none()) {
_P_x = NULL;
} else {
auto _P_x_array = py::array_t<OSQPFloat>(P_x);
_P_x = (OSQPFloat *)_P_x_array.data();
_P_n = _P_x_array.size();
py::array_t<OSQPFloat> _P_x_arr, _A_x_arr;
py::array_t<OSQPInt> _P_i_arr, _A_i_arr;

if (!P_x.is_none()) {
_P_x_arr = py::array_t<OSQPFloat>(P_x);
_P_x = (OSQPFloat *)_P_x_arr.data();
_P_n = _P_x_arr.size();
}

if (P_i.is_none()) {
_P_i = NULL;
} else {
auto _P_i_array = py::array_t<OSQPInt>(P_i);
_P_i = (OSQPInt *)_P_i_array.data();
_P_n = _P_i_array.size();
if (!P_i.is_none()) {
_P_i_arr = py::array_t<OSQPInt>(P_i);
_P_i = (OSQPInt *)_P_i_arr.data();
_P_n = _P_i_arr.size();
}

if (A_x.is_none()) {
_A_x = NULL;
} else {
auto _A_x_array = py::array_t<OSQPFloat>(A_x);
_A_x = (OSQPFloat *)_A_x_array.data();
_A_n = _A_x_array.size();
if (!A_x.is_none()) {
_A_x_arr = py::array_t<OSQPFloat>(A_x);
_A_x = (OSQPFloat *)_A_x_arr.data();
_A_n = _A_x_arr.size();
}

if (A_i.is_none()) {
_A_i = NULL;
} else {
auto _A_i_array = py::array_t<OSQPInt>(A_i);
_A_i = (OSQPInt *)_A_i_array.data();
_A_n = _A_i_array.size();
if (!A_i.is_none()) {
_A_i_arr = py::array_t<OSQPInt>(A_i);
_A_i = (OSQPInt *)_A_i_arr.data();
_A_n = _A_i_arr.size();
}

return osqp_update_data_mat(&{{prefix}}solver, _P_x, _P_i, _P_n, _A_x, _A_i, _A_n);
Expand Down
3 changes: 3 additions & 0 deletions src/osqp/codegen/pywrapper/setup.py.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ class CmdCMakeBuild(build_ext):
cmake_args = [
f'-DCMAKE_LIBRARY_OUTPUT_DIRECTORY={extdir}',
f'-DPYTHON_EXECUTABLE={sys.executable}',
f'-DPython_EXECUTABLE={sys.executable}',
f'-DPython3_EXECUTABLE={sys.executable}',
'-DPYBIND11_FINDPYTHON=NEW',
]

build_args = []
Expand Down
Loading