Ok. I figured out the difference. In my application, I have 1 LP (master) and many MILPs (subproblems). Each one is its own OsiCpx. For the master, I shut off presolve. I did not want this shut off for the MILPs. However, give the current OsiCpx setup, there is only one CpxEnv and parameters in Cpx are set through that env. So, when I shutoff presolve in the master it shut off presolve everywhere! Besides the threading issue, this is another reason I would think that we do not want one static env in OsiCpx. <br>

<br>I will post patch to ticket.<br><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;">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.<div>

<div></div><div class="h5"><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>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><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" target="_blank">osi-bounces@list.coin-or.org</a><br>
&gt;                 [<a href="mailto:osi-bounces@list.coin-or.org" target="_blank">osi-bounces@list.coin-or.org</a>] On<br>
&gt;                 &gt; Behalf Of Matthew Galati [<a href="mailto:magh@lehigh.edu" target="_blank">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" target="_blank">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" target="_blank">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>                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>
</div></div></blockquote></div><br>