#17320: Memory leaks with LP Solvers are back
-------------------------------------+-------------------------------------
       Reporter:  pmueller           |        Owner:
           Type:  defect             |       Status:  new
       Priority:  major              |    Milestone:  sage-6.4
      Component:  linear             |   Resolution:
  programming                        |    Merged in:
       Keywords:                     |    Reviewers:
        Authors:                     |  Work issues:
Report Upstream:  N/A                |       Commit:
         Branch:                     |  bc20667184ca8209776d8c363df2aa3e65994287
  u/nbruin/memory_leaks_with_lp_solvers_are_back|     Stopgaps:
   Dependencies:                     |
-------------------------------------+-------------------------------------

Comment (by ncohen):

 Hello,

 > It seems to me that only committing to the new model by assigning it to
 `self.model` at the very end is a design feature:

 I wrote this file myself, and I do not think that this had the slightest
 importance to me at that time.

 > it means that if the computation fails for any reason,

 When an exception is raised in that code, it is almost always because the
 problem is infeasible. This is not a "failure", it is the actual answer
 the user is looking for.

 > the object `self` is unaffected and hence still in a consistent state.
 It's also better for future development, because as long as model is
 private, there is no lock required to modify it. Once it's exported to
 `self.model`, you'd need to lock self before `self.model` is changed.
 Python currently doesn't support such multiprocessing programming anyway,
 but having changes in global state as atomic as possible is generally a
 good feature, because it reduces the possibility for unexpected
 interactions between multiple threads (the GIL does get released every now
 and again ...)

 If your worry is that in a multithread Python program with a
 MixedIntegerLinearProgram instance `p` the function `p.solve()` may be
 called simultaneously from different processors, I believe that you can
 forget it. Even if that made the sligthest sense, you would have many
 other places in the code to re-read and adapt.

 > With your change, the model that just experienced an error is now stored
 in `self`. It could be convenient to have it available for further
 analysis, so a priori it's not clear which design is more useful. It
 depends on the details of what the code does and how it does it.

 Well, again what you call an 'error' is just a certificate of
 infeasibiity, and this is definitely good to have around. But the fact
 that all doctests pass (even in the graph/ folder) indicates that this
 change brings no real problem.

 > Furthermore, there is still this code between `model` allocation and
 committing to `self.model=model`.
 > {{{
 >         model.setLogLevel(self.model.logLevel())
 >
 >         # multithreading
 >         import multiprocessing
 >         model.setNumberThreads(multiprocessing.cpu_count())
 >
 >         model.branchAndBound()
 > }}}
 > which looks like it's quite nontrivial and hence could raise errors by
 itself. You'd still have a leak then. So either guard that with a
 `try/finally`, in which case you might as well stick with the guard all
 the way, or move the `self.model=model` even higher.

 Please move that line higher if you care. I believe that you are being
 worried unnecessarily.

 Nathann

--
Ticket URL: <http://trac.sagemath.org/ticket/17320#comment:15>
Sage <http://www.sagemath.org>
Sage: Creating a Viable Open Source Alternative to Magma, Maple, Mathematica, 
and MATLAB

-- 
You received this message because you are subscribed to the Google Groups 
"sage-trac" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sage-trac.
For more options, visit https://groups.google.com/d/optout.

Reply via email to