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

Stefan Vigerske stefan at vigerske.de
Sun Aug 10 11:26:22 EDT 2008


Hi,

thanks for finding an explanation for this.
Clp also got into some infinite loop at this method when using 
Intel32bit/Linux/gcc3.3.5 for me, but I couldn't find where the problem is.
I've submitted your fix to some inofficial branch of Clp, I hope it will 
make it into the regular version soon.

Thanks,
Stefan

Arno Schödl wrote:
> 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
> 
> 
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> Clp mailing list
> Clp at list.coin-or.org
> http://list.coin-or.org/mailman/listinfo/clp





More information about the Clp mailing list