[Clp] patch for Visual C++ floating-point model problem

Arno Schödl aschoedl at think-cell.com
Sat Aug 9 17:27:29 EDT 2008


Hello,

 

I am compiling Clp with Visual C++ 2008. In Release build, I got an infinite recursion in the function below because the condition tolerance>saveTolerance always evaluated to true, although tolerance was in fact never touched after copying it into saveTolerance. The problem was that saveTolerance was stored in memory, and thus was truncated to 64 bit. tolerance was kept in an FPU register with all 80 bits. Thus tolerance was slightly larger than saveTolerance in the comparison. I verified this from the generated assembly code.

 

/fp:precise did not solve the problem (and did not either in Visual C++ 2005 SP1), although from the documentation, it should, because assignments should force rounding. In fact, the generated code still kept tolerance in an FPU register. /fp:strict fixed it but is not recommended for performance. I propose the patch below to side-step the problem. There is one caveat where I would need Lou's input: if model_->largestDualError() is only slightly larger than model_->largestPrimalError(), it is conceivable that after the multiplication, still tolerance==saveTolerance, and we still recurse. Does that break the code?

 

Thank you for help,

 

Arno

 

 

--- .\Clp\src\ClpDualRowSteepest.cpp      Sat Aug  9 23:05:22 2008

+++ .\Clp\src\ClpDualRowSteepest.cpp      Sat Aug  9 22:36:45 2008

@@ -168,7 +168,6 @@

   // But cap

   tolerance = CoinMin(1000.0,tolerance);

   tolerance *= tolerance; // as we are using squares

-  double saveTolerance = tolerance;

   double * solution = model_->solutionRegion();

   double * lower = model_->lowerRegion();

   double * upper = model_->upperRegion();

@@ -223,10 +222,13 @@

   if (model_->numberIterations()<0)

     printf("aac_p it %d\n",model_->numberIterations());

 #endif

+  bool bToleranceIncreased=false;

   if(model_->numberIterations()<model_->lastBadIteration()+200) {

     // we can't really trust infeasibilities if there is dual error

-    if (model_->largestDualError()>model_->largestPrimalError())

+     if (model_->largestDualError()>model_->largestPrimalError()) {

       tolerance *= CoinMin(model_->largestDualError()/model_->largestPrimalError(),1000.0);

+      bToleranceIncreased=true;

+     }

   }

   int numberWanted;

   if (mode_<2 ) {

@@ -318,7 +320,7 @@

       break;

   }

   //printf("smallest %g largest %g\n",smallestWeight,largestWeight);

-  if (chosenRow<0&& tolerance>saveTolerance) {

+  if (chosenRow<0&& bToleranceIncreased) {

     // won't line up with checkPrimalSolution - do again

     double saveError = model_->largestDualError();

     model_->setLargestDualError(0.0);

 


--
Dr. Arno Schoedl · aschoedl at think-cell.com 
Technical Director 
 
think-cell Software GmbH · Invalidenstr. 34 · 10115 Berlin, Germany 
http://www.think-cell.com · phone +49-30-666473-10 · fax +49-30-666473-19
Geschäftsführer: Dr. Markus Hannebauer, Dr. Arno Schoedl · Amtsgericht Charlottenburg, HRB 85229

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://list.coin-or.org/pipermail/clp/attachments/20080809/c46816a5/attachment.html>


More information about the Clp mailing list