[Clp] patch for Visual C++ floating-point model problem
John J Forrest
jjforre at us.ibm.com
Mon Aug 11 06:37:24 EDT 2008
Arno,
Thanks for your patch. I have put into trunk and Clp stable 1.7 (for Cbc
stable 2.1).
John
From: Arno Schödl <aschoedl at think-cell.com>
To: <clp at list.coin-or.org>
Date: 08/09/2008 05:40 PM
Subject: [Clp] patch for Visual C++ floating-point model problem
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 http://www.think-cell.com
Invalidenstr. 34 phone +49-30-666473-10
10115 Berlin, Germany 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