Will do. But I am investigating some odd behavior. The duals I get from CPX after a few iterations of my algorithm are different with this patch versus without. I don&#39;t understand why since the only change was to move the env/lp vars from static to class members. I will get back to you.<br>

<br><div class="gmail_quote"><br><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><div class="im">On Mon, 2009-09-14 at 22:59 -0400, Matthew Galati wrote:<br>


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