Here's a patch (against Osi releases 0.100.0) for what I did to make it thread-safe (at least fixing the obvious stuff). <br><br>Thanks,<br>Matt<br><br><br><br><br><br>magh@shark:~/COIN/coin-Decomp/Osi/src/OsiCpx$ svn diff OsiCpxSolverInterface.cpp<br>
Index: OsiCpxSolverInterface.cpp<br>===================================================================<br>--- OsiCpxSolverInterface.cpp (revision 1399)<br>+++ OsiCpxSolverInterface.cpp (working copy)<br>@@ -30,7 +30,7 @@<br>
#include "CoinWarmStartBasis.hpp"<br><br><br>-// #define DEBUG 1<br>+//#define DEBUG 1<br><br> #ifdef DEBUG<br> #define debugMessage printf<br>@@ -1291,6 +1291,7 @@<br> {<br> double *rowslack = new double[nrows];<br>
int err = CPXgetmipslack( env_, getMutableLpPtr(), rowslack, 0, nrows-1 );<br>+ printf("err=%d\n", err);<br> if ( err == CPXERR_NO_SOLN || err == CPXERR_NO_INT_SOLN )<br> CoinFillN( rowact_, nrows, 0.0 );<br>
else<br>@@ -1304,6 +1305,7 @@<br> else<br> {<br> int err = CPXgetax( env_, getMutableLpPtr(), rowact_, 0, nrows-1 );<br>+ printf("err2=%d\n", err);<br> if ( err == CPXERR_NO_SOLN )<br>
CoinFillN( rowact_, nrows, 0.0 );<br> else<br>@@ -2558,8 +2560,10 @@<br><br> void OsiCpxSolverInterface::incrementInstanceCounter()<br> {<br>- if ( numInstances_ == 0 )<br>- {<br>+ printf("numInstances_ = %d\n", numInstances_);<br>
+ //MVG<br>+ if ( numInstances_ == 0 )<br>+ {<br> int err;<br><br> #if CPX_VERSION >= 800<br>@@ -2568,6 +2572,8 @@<br> env_ = CPXopenCPLEXdevelop( &err );<br> #endif<br><br>+ printf("open env = %p\n", env_);<br>
+<br> checkCPXerror( err, "CPXopenCPLEXdevelop", "incrementInstanceCounter" );<br> assert( env_ != NULL );<br> #ifndef NDEBUG<br>@@ -2580,7 +2586,7 @@<br> //CPXsetlogfile( env_, fp );<br>
err = sscanf( CPXversion( env_ ), "%d.%d.%d", &cpxVersionMajor_, &cpxVersionMinor_, &cpxVersionMinorMinor_ );<br> assert( err == 3 );<br>- }<br>+ }<br> numInstances_++;<br> }<br>
<br>
@@ -2636,7 +2642,13 @@<br> matrixByCol_(NULL),<br> coltype_(NULL),<br> coltypesize_(0),<br>- probtypemip_(false)<br>+ probtypemip_(false),<br>+ //MVG<br>+ env_(NULL),<br>+ cpxVersionMajor_(0),<br>
+ cpxVersionMinor_(0),<br>+ cpxVersionMinorMinor_(0),<br>+ numInstances_(0)<br> {<br> debugMessage("OsiCpxSolverInterface::OsiCpxSolverInterface()\n");<br><br>@@ -2805,12 +2817,13 @@<br> //------------------------------------------------------------------<br>
// Static data<br> //------------------------------------------------------------------<br>-CPXENVptr OsiCpxSolverInterface::env_ = NULL;<br>+//CPXENVptr OsiCpxSolverInterface::env_ = NULL;<br><br>-int OsiCpxSolverInterface::cpxVersionMajor_ = 0;<br>
-int OsiCpxSolverInterface::cpxVersionMinor_ = 0;<br>-int OsiCpxSolverInterface::cpxVersionMinorMinor_ = 0;<br>-unsigned int OsiCpxSolverInterface::numInstances_ = 0;<br>+//MVG<br>+//int OsiCpxSolverInterface::cpxVersionMajor_ = 0;<br>
+//int OsiCpxSolverInterface::cpxVersionMinor_ = 0;<br>+//int OsiCpxSolverInterface::cpxVersionMinorMinor_ = 0;<br>+//unsigned int OsiCpxSolverInterface::numInstances_ = 0;<br><br> //-------------------------------------------------------------------<br>
// Get pointer to CPXLPptr.<br><br><br><br><br><br>magh@shark:~/COIN/coin-Decomp/Osi/src/OsiCpx$ svn diff OsiCpxSolverInterface.hpp<br>Index: OsiCpxSolverInterface.hpp<br>===================================================================<br>
--- OsiCpxSolverInterface.hpp (revision 1399)<br>+++ OsiCpxSolverInterface.hpp (working copy)<br>@@ -641,7 +641,8 @@<br> 1 from 0.<br> </ul><br> */<br>- static void incrementInstanceCounter();<br>
+ //static void incrementInstanceCounter();<br>+ void incrementInstanceCounter(); //MVG<br><br> /** CPLEX has a context which should be deleted after CPLEX calls.<br> This method:<br>@@ -651,10 +652,12 @@<br>
0 from 1.<br>
</ul><br> */<br>- static void decrementInstanceCounter();<br>+ void decrementInstanceCounter();//MVG<br>+ //static void decrementInstanceCounter();<br><br> /// Return the number of instances of instantiated objects using CPLEX services.<br>
- static unsigned int getNumInstances();<br>+ //static unsigned int getNumInstances();<br>+ unsigned int getNumInstances();//MVG<br> //@}<br> //@}<br><br>@@ -787,13 +790,20 @@<br> /**@name Private static class data */<br>
//@{<br> /// CPLEX environment pointer<br>- static CPXENVptr env_;<br>+ //static CPXENVptr env_;<br>+ CPXENVptr env_; //MVG<br> /// CPLEX version<br>- static int cpxVersionMajor_;<br>- static int cpxVersionMinor_;<br>
- static int cpxVersionMinorMinor_;<br>+ //static int cpxVersionMajor_;<br>+ //static int cpxVersionMinor_;<br>+ //static int cpxVersionMinorMinor_;<br> /// Number of live problem instances<br>- static unsigned int numInstances_;<br>
+ //static unsigned int numInstances_;<br>+ /// CPLEX version<br>+ int cpxVersionMajor_;<br>+ int cpxVersionMinor_;<br>+ int cpxVersionMinorMinor_;<br>+ /// Number of live problem instances<br>+ unsigned int numInstances_;<br>
//@}<br><br><br><br><br><br><br><br><div class="gmail_quote"><span dir="ltr"></span><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Ok. Thanks Matt. For the tests I have run so far, my simple fix of removing all the static vars from OsiCpx seems to have worked. However, my usage for this case is very simple. I am essentially just solving the same N models on T threads over and over again with just a minor problem modifications. So, I think the thread-safey in my case is primarly cplex's - which we know that part is fine. The main "connector" through OSI seems to be the env_, lp_ vars - of which env_ was static.<br>
<br>I'll definitely keep my eye out for other issues and I'll let you know / add tickets.<br><br>Thanks,<br>Matt G<div><div></div><div class="h5"><br><br><br><div class="gmail_quote"><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Matt-<br>
<br>
I'm not sure that thread safety is quite that simple. You may have<br>
eliminated some of the obvious races, but it wouldn't surprise me to<br>
find other hidden ones that don't crop up as frequently. OSI really<br>
needs a more comprehensive audit for thread safety, which we are aware<br>
of and which is on my agenda.<br>
<br>
If you have patches that you think make a good starting point, I'm glad<br>
to have them. The best place to keep them is probably attached to a<br>
ticket.<br>
<br>
Thanks.<br>
<br>
Matt<br>
<div><div></div><div><br>
<br>
<br>
On Fri, 2009-08-28 at 01:57 -0400, Matthew Galati wrote:<br>
> FYI. If I remove all the references to static env_, version, etc...<br>
> things seem to work fine now. OsiCpx is then thread-safe.<br>
><br>
> Can this be changed? or at least provided as an option? It is a shame<br>
> if one cannot use Osi in a multi-threaded environment.<br>
> ________________________________________<br>
> From: <a href="mailto:osi-bounces@list.coin-or.org" target="_blank">osi-bounces@list.coin-or.org</a> [<a href="mailto:osi-bounces@list.coin-or.org" target="_blank">osi-bounces@list.coin-or.org</a>] On<br>
> Behalf Of Matthew Galati [<a href="mailto:magh@lehigh.edu" target="_blank">magh@lehigh.edu</a>]<br>
> Sent: Thursday, August 27, 2009 11:55 PM<br>
> To: <a href="mailto:osi@list.coin-or.org" target="_blank">osi@list.coin-or.org</a><br>
> Subject: [Osi] osicpx threaded<br>
><br>
> Has anyone successfully used more than one instance/thread of OsiCpx<br>
> simultaneously? I am trying to do this. Constructing 2 instances of<br>
> OsiCpx and using standard pthreads, solve two MILPs on 2 threads. It<br>
> crashes. Valgrind/Helgrind is showing lots of potential race<br>
> conditions. Looking a little deeper into OsiCpx, I noticed that<br>
> although I have two different CpxLp ptrs, I have one CpxEnv ptr. In<br>
> fact, the cpx env is a static variable in OsiCpx. Doesn't this make<br>
> OsiCpx not thread-safe? Is there any easy way around this?<br>
><br>
> Thanks,<br>
> Matt<br>
><br>
><br>
</div></div>> _______________________________________________<br>
> Osi mailing list<br>
> <a href="mailto:Osi@list.coin-or.org" target="_blank">Osi@list.coin-or.org</a><br>
> <a href="http://list.coin-or.org/mailman/listinfo/osi" target="_blank">http://list.coin-or.org/mailman/listinfo/osi</a><br>
<font color="#888888">--<br>
Matthew Saltzman<br>
<br>
Clemson University Math Sciences<br>
mjs AT clemson DOT edu<br>
<a href="http://www.math.clemson.edu/%7Emjs" target="_blank">http://www.math.clemson.edu/~mjs</a><br>
</font></blockquote></div><br>
</div></div></blockquote></div><br>