[Osi] osicpx threaded
Matthew Galati
magh at lehigh.edu
Tue Sep 15 12:46:18 EDT 2009
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.
I will post patch to ticket.
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'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.
>
>
>
>
> On Mon, 2009-09-14 at 22:59 -0400, Matthew Galati wrote:
>> > 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. Can you add the patch to the ticket?
>>
>> >
>> > 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>
>> >
>> >
>> >
>> --
>> 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/20090915/21f201ed/attachment.html>
More information about the Osi
mailing list