Search code examples
c++scip

How to copy a SoPlex model?


I am using SoPlex to set up a lp and solve it. I then try to make a copy of the original lp and modify it. My code looks like this:

int main()
{
   using namespase soplex;
   SoPlex spx;
   // add columns
   // add rows
   auto status = spx.optimize();

   SoPlex copy(spx);
   // modify some columns

   status = copy.optimize();

   return 0;
}

When I run my code in valgrind, I notice that memory allocated by methods inside the SoPlex copy constructor are not freed.

Is there a memory leak inside SoPlex or am I not using it correctly?


Solution

  • You are using the copy functionality correctly. There is indeed a memory leak in SoPlex that is going to be fixed in the next version.

    In the meantime you could try to apply this patch for SoPlex-4.0.1:

    diff --git a/src/soplex/slufactor.cpp b/src/soplex/slufactor.cpp
    index ae41604..a3314d8 100644
    --- a/src/soplex/slufactor.cpp
    +++ b/src/soplex/slufactor.cpp
    @@ -1230,8 +1230,6 @@ SLUFactor::SLUFactor(const SLUFactor& old)
        l.rperm     = 0;
    
        solveCount = 0;
    -   solveTime = TimerFactory::createTimer(timerType);
    -   factorTime = TimerFactory::createTimer(timerType);
    
        try
        {
    @@ -1326,16 +1324,23 @@ void SLUFactor::freeAll()
    
        if(l.rperm)
           spx_free(l.rperm);
    +
    +   if(solveTime)
    +   {
    +      solveTime->~Timer();
    +      spx_free(solveTime);
    +   }
    +
    +   if(factorTime)
    +   {
    +      factorTime->~Timer();
    +      spx_free(factorTime);
    +   }
     }
    
     SLUFactor::~SLUFactor()
     {
        freeAll();
    -
    -   solveTime->~Timer();
    -   factorTime->~Timer();
    -   spx_free(solveTime);
    -   spx_free(factorTime);
     }
    
     static Real betterThreshold(Real th)
    diff --git a/src/soplex/spxbasis.cpp b/src/soplex/spxbasis.cpp
    index 6370e89..40d201b 100644
    --- a/src/soplex/spxbasis.cpp
    +++ b/src/soplex/spxbasis.cpp
    @@ -1363,6 +1363,7 @@ SPxBasis::~SPxBasis()
           factor = 0;
        }
    
    +   theTime->~Timer();
        spx_free(theTime);
     }