[Osi] osicpx threaded

Matthew Galati magh at lehigh.edu
Mon Sep 14 22:59:10 EDT 2009


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).

Thanks,
Matt





magh at shark:~/COIN/coin-Decomp/Osi/src/OsiCpx$ svn diff
OsiCpxSolverInterface.cpp
Index: OsiCpxSolverInterface.cpp
===================================================================
--- OsiCpxSolverInterface.cpp   (revision 1399)
+++ OsiCpxSolverInterface.cpp   (working copy)
@@ -30,7 +30,7 @@
 #include "CoinWarmStartBasis.hpp"


-// #define DEBUG 1
+//#define DEBUG 1

 #ifdef DEBUG
 #define debugMessage printf
@@ -1291,6 +1291,7 @@
           {
              double *rowslack = new double[nrows];
              int err = CPXgetmipslack( env_, getMutableLpPtr(), rowslack,
0, nrows-1 );
+            printf("err=%d\n", err);
              if ( err == CPXERR_NO_SOLN || err == CPXERR_NO_INT_SOLN )
                 CoinFillN( rowact_, nrows, 0.0 );
              else
@@ -1304,6 +1305,7 @@
           else
           {
              int err = CPXgetax( env_, getMutableLpPtr(), rowact_, 0,
nrows-1 );
+            printf("err2=%d\n", err);
              if ( err == CPXERR_NO_SOLN )
                 CoinFillN( rowact_, nrows, 0.0 );
              else
@@ -2558,8 +2560,10 @@

 void OsiCpxSolverInterface::incrementInstanceCounter()
 {
-  if ( numInstances_ == 0 )
-    {
+   printf("numInstances_ = %d\n", numInstances_);
+   //MVG
+   if ( numInstances_ == 0 )
+   {
       int err;

 #if CPX_VERSION >= 800
@@ -2568,6 +2572,8 @@
       env_ = CPXopenCPLEXdevelop( &err );
 #endif

+      printf("open env = %p\n", env_);
+
       checkCPXerror( err, "CPXopenCPLEXdevelop", "incrementInstanceCounter"
);
       assert( env_ != NULL );
 #ifndef NDEBUG
@@ -2580,7 +2586,7 @@
       //CPXsetlogfile( env_, fp );
       err = sscanf( CPXversion( env_ ), "%d.%d.%d", &cpxVersionMajor_,
&cpxVersionMinor_, &cpxVersionMinorMinor_ );
       assert( err == 3 );
-    }
+   }
   numInstances_++;
 }

@@ -2636,7 +2642,13 @@
     matrixByCol_(NULL),
     coltype_(NULL),
     coltypesize_(0),
-    probtypemip_(false)
+    probtypemip_(false),
+    //MVG
+    env_(NULL),
+    cpxVersionMajor_(0),
+    cpxVersionMinor_(0),
+    cpxVersionMinorMinor_(0),
+    numInstances_(0)
 {
   debugMessage("OsiCpxSolverInterface::OsiCpxSolverInterface()\n");

@@ -2805,12 +2817,13 @@
 //------------------------------------------------------------------
 // Static data
 //------------------------------------------------------------------
-CPXENVptr OsiCpxSolverInterface::env_ = NULL;
+//CPXENVptr OsiCpxSolverInterface::env_ = NULL;

-int OsiCpxSolverInterface::cpxVersionMajor_ = 0;
-int OsiCpxSolverInterface::cpxVersionMinor_ = 0;
-int OsiCpxSolverInterface::cpxVersionMinorMinor_ = 0;
-unsigned int OsiCpxSolverInterface::numInstances_ = 0;
+//MVG
+//int OsiCpxSolverInterface::cpxVersionMajor_ = 0;
+//int OsiCpxSolverInterface::cpxVersionMinor_ = 0;
+//int OsiCpxSolverInterface::cpxVersionMinorMinor_ = 0;
+//unsigned int OsiCpxSolverInterface::numInstances_ = 0;

 //-------------------------------------------------------------------
 // Get pointer to CPXLPptr.





magh at shark:~/COIN/coin-Decomp/Osi/src/OsiCpx$ svn diff
OsiCpxSolverInterface.hpp
Index: OsiCpxSolverInterface.hpp
===================================================================
--- OsiCpxSolverInterface.hpp   (revision 1399)
+++ OsiCpxSolverInterface.hpp   (working copy)
@@ -641,7 +641,8 @@
       1 from 0.
       </ul>
   */
-  static void incrementInstanceCounter();
+   //static void incrementInstanceCounter();
+   void incrementInstanceCounter(); //MVG

   /** CPLEX has a context which should be deleted after CPLEX calls.
       This method:
@@ -651,10 +652,12 @@
       0 from 1.
       </ul>
   */
-  static void decrementInstanceCounter();
+   void decrementInstanceCounter();//MVG
+   //static void decrementInstanceCounter();

   /// Return the number of instances of instantiated objects using CPLEX
services.
-  static unsigned int getNumInstances();
+  //static unsigned int getNumInstances();
+   unsigned int getNumInstances();//MVG
   //@}
   //@}

@@ -787,13 +790,20 @@
   /**@name Private static class data */
   //@{
   /// CPLEX environment pointer
-  static CPXENVptr env_;
+   //static CPXENVptr env_;
+   CPXENVptr env_; //MVG
   /// CPLEX version
-  static int cpxVersionMajor_;
-  static int cpxVersionMinor_;
-  static int cpxVersionMinorMinor_;
+  //static int cpxVersionMajor_;
+  //static int cpxVersionMinor_;
+  //static int cpxVersionMinorMinor_;
   /// Number of live problem instances
-  static unsigned int numInstances_;
+  //static unsigned int numInstances_;
+  /// CPLEX version
+  int cpxVersionMajor_;
+  int cpxVersionMinor_;
+  int cpxVersionMinorMinor_;
+  /// Number of live problem instances
+  unsigned int numInstances_;
   //@}








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.
>
> I'll definitely keep my eye out for other issues and I'll let you know /
> add tickets.
>
> Thanks,
> Matt G
>
>
>
>
> Matt-
>>
>> I'm not sure that thread safety is quite that simple.  You may have
>> eliminated some of the obvious races, but it wouldn't surprise me to
>> find other hidden ones that don't crop up as frequently.  OSI really
>> needs a more comprehensive audit for thread safety, which we are aware
>> of and which is on my agenda.
>>
>> If you have patches that you think make a good starting point, I'm glad
>> to have them.  The best place to keep them is probably attached to a
>> ticket.
>>
>> Thanks.
>>
>>                Matt
>>
>>
>>
>> On Fri, 2009-08-28 at 01:57 -0400, Matthew Galati wrote:
>> > FYI. If I remove all the references to static env_, version, etc...
>> > things seem to work fine now. OsiCpx is then thread-safe.
>> >
>> > Can this be changed? or at least provided as an option? It is a shame
>> > if one cannot use Osi in a multi-threaded environment.
>> > ________________________________________
>> > From: osi-bounces at list.coin-or.org [osi-bounces at list.coin-or.org] On
>> > Behalf Of Matthew Galati [magh at lehigh.edu]
>> > Sent: Thursday, August 27, 2009 11:55 PM
>> > To: osi at list.coin-or.org
>> > Subject: [Osi] osicpx threaded
>> >
>> > Has anyone successfully used more than one instance/thread of OsiCpx
>> > simultaneously? I am trying to do this. Constructing 2 instances of
>> > OsiCpx and using standard pthreads, solve two MILPs on 2 threads. It
>> > crashes. Valgrind/Helgrind is showing lots of potential race
>> > conditions. Looking a little deeper into OsiCpx, I noticed that
>> > although I have two different CpxLp ptrs, I have one CpxEnv ptr. In
>> > fact, the cpx env is a static variable in OsiCpx. Doesn't this make
>> > OsiCpx not thread-safe? Is there any easy way around this?
>> >
>> > Thanks,
>> > Matt
>> >
>> >
>> > _______________________________________________
>> > Osi mailing list
>> > Osi at list.coin-or.org
>> > http://list.coin-or.org/mailman/listinfo/osi
>> --
>>                Matthew Saltzman
>>
>> Clemson University Math Sciences
>> mjs AT clemson DOT edu
>> http://www.math.clemson.edu/~mjs <http://www.math.clemson.edu/%7Emjs>
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://list.coin-or.org/pipermail/osi/attachments/20090914/74b440d6/attachment.html>


More information about the Osi mailing list