-
Notifications
You must be signed in to change notification settings - Fork 44
Description
Question about memory management in PyOSQPSolver::get_solution()
Version
- osqp-python: v1.0.5
- Python: 3.10
- OS: Linux
Background
I'm investigating a memory growth issue in my application and Valgrind is reporting what appears to be a memory leak originating from PyOSQPSolver::get_solution(). However, I suspect I might be misunderstanding the intended design.
Code in Question
In src/bindings.cpp.in (lines 167-171):
PyOSQPSolution& PyOSQPSolver::get_solution() {
PyOSQPSolution* solution = new PyOSQPSolution(*this->_solver->solution, this->m, this->n);
return *solution;
}Combined with the binding (line 492):
.def_property_readonly("solution", &PyOSQPSolver::get_solution, py::return_value_policy::reference)My Understanding (possibly incorrect)
From my reading:
- Each call to
get_solution()allocates a newPyOSQPSolutionon the heap py::return_value_policy::referencetells pybind11 not to manage this object's lifetime- I don't see where these objects are deleted
However, the Python layer (interface.py lines 426-429) accesses .solution multiple times per solve:
x=self._solver.solution.x,
y=self._solver.solution.y,
prim_inf_cert=self._solver.solution.prim_inf_cert,
dual_inf_cert=self._solver.solution.dual_inf_cert,Valgrind Output
My application with ~400k solves shows:
==3130== 50,680,976 bytes in 3,167,559 blocks are definitely lost
==3130== at 0x483CF83: operator new(unsigned long)
==3130== by 0x14D53CA21: PyOSQPSolver::get_solution() (bindings.cpp:169)
My Question
Am I missing something about how these objects are managed?
I'm hesitant to conclude this is a bug because:
- This code has been in use for a while
- There might be a cleanup path I'm not seeing
- Perhaps the
referencepolicy has different semantics than I understand
Could someone clarify the intended lifetime management for these PyOSQPSolution objects? Is there a design reason for allocating them on the heap with new rather than returning by value?
Thank you!