-
Notifications
You must be signed in to change notification settings - Fork 115
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CbcMain not thread safe #332
Comments
It's not clear to me, but did you build with |
Yes In the DIp code (stable/0.95) I found and underneath it uses |
Hmm, I don't think we did encounter issues the last time we experimented with it, but it's been a while. Since I'm digging around in the code right now anyway, I'll see if I can see any fix for this. Yes, the results will likely not be as good when calling |
Cool. That would be super helpful |
I think you just have to add
-DCBC_THREAD_SAFE to your configuration. Without that I could get
errors similar to the ones you describe.
I could not get std::execution::par to run but going back to pthreads
the following worked with sample parameters of
-log 1 -ratio 0.001 -seconds 1000 -cutoff 1.0e8 -solve
My code was
int main(int argc, const char *argv[])
{
#define NUM_PROB 10
OsiClpSolverInterface solver[NUM_PROB];
CbcModel * model[NUM_PROB];
pthread_t threadId[NUM_PROB]={0};;
const char * mpsFiles[NUM_PROB] = {"10teams", "enigma", "misc07",
"stein45",
"air03","bell3a","bell5","dcmulti",
"gesa2","p2756"};
for (int iModel = 0;iModel < NUM_PROB;iModel++) {
char name[50];
strcpy(name,"~/miplib3/");
strcat(name,mpsFiles[iModel]);
int numMpsReadErrors = solver[iModel].readMps(name, "");
if (numMpsReadErrors != 0) {
printf("%d errors reading MPS file\n", numMpsReadErrors);
return numMpsReadErrors;
}
}
for (int iModel = 0;iModel < NUM_PROB;iModel++) {
pthread_create(&threadId[iModel], NULL,
doLpThread,&solver[iModel]);
}
// wait
for (int iModel = 0;iModel < NUM_PROB;iModel++)
pthread_join(threadId[iModel],NULL);
// do MIP
mipBundle bundle[NUM_PROB];
for (int iModel = 0;iModel < NUM_PROB;iModel++) {
// back to old printing
solver[iModel].getModelPtr()->setMinIntervalProgressUpdate(-1000.0);
model[iModel]= new CbcModel(solver[iModel]);
bundle[iModel].model = model[iModel];
bundle[iModel].argc = argc;
bundle[iModel].argv = argv;
}
for (int iModel = 0;iModel < NUM_PROB;iModel++) {
pthread_create(&threadId[iModel], NULL,
doMipThread,&bundle[iModel]);
}
// wait
for (int iModel = 0;iModel < NUM_PROB;iModel++) {
pthread_join(threadId[iModel],NULL);
printf("Model %d finished\n",iModel);
}
for (int iModel = 0;iModel < NUM_PROB;iModel++)
printf("Model %d took %d nodes with objective %g\n",
iModel,model[iModel]->getNodeCount(),
model[iModel]->getObjValue());
return 0;
}
John Forrest
…On 07/09/2020 15:14, Simon Spoorendonk wrote:
I am trying to run some MIP problems in parallel using the
|CbcMain0/CbcMain1| pattern.
I am on https://github.com/coin-or/Cbc/tree/stable/2.10
Problem is both on Linux and Windows.
My code snippet is
std::vector<int> probIndices(10);
std::iota(probIndices.begin(), probIndices.end(), 0);
std::for_each(std::execution::par,
std::begin(probIndices),
std::end(probIndices),
[&](int idx) {
OsiClpSolverInterface clp;
clp.readLp("folio10_7.lp");
clp.initialSolve();
clp.resolve();
CbcModelcbcModel(clp);
CbcMain0(cbcModel);
const char *argv[20];
int argc =0;
std::string cbcExe ="cbc";
std::string cbcSolve ="-solve";
std::string cbcQuit ="-quit";
std::string cbcLog ="-log";
std::string cbcLogSet ="3";
std::string cbcGap ="-ratio";
std::string cbcGapSet ="0.05";
std::string cbcTime ="-seconds";
std::string cbcTimeSet ="1000";
std::string cbcCutoff ="-cutoff";
std::string cbcCutoffSet ="1000000";
argv[argc++] = cbcExe.c_str();
argv[argc++] = cbcLog.c_str();
argv[argc++] = cbcLogSet.c_str();
argv[argc++] = cbcGap.c_str();
argv[argc++] = cbcGapSet.c_str();
argv[argc++] = cbcTime.c_str();
argv[argc++] = cbcTimeSet.c_str();
argv[argc++] = cbcCutoff.c_str();
argv[argc++] = cbcCutoffSet.c_str();
argv[argc++] = cbcSolve.c_str();
argv[argc++] = cbcQuit.c_str();
CbcMain1(argc, argv, cbcModel);
if (cbcModel.status() == -1)
{
throw std::domain_error("CBC fail");
}
});
return 0;
It fails when parsing the commandline parameters (I think) The output is
like
...
Welcome to the CBC MILP Solver
Version: 2.10
Build Date: Sep 1 2020
command line - cbc -log 3 -ratio 0.05 -seconds 1000 -cutoff 1000000 -solve -quit (default strategy 1)
logLevel was changed from 1 to 3
ratioGap was changed from 0 to 0.05
String of -log is illegalfor double parameter seconds value remains -1
No matchfor 3 -? for list of commands
Welcome to the CBC MILP Solver
Version: 2.10
Build Date: Sep 1 2020
command line - cbc -log 3 -ratio 0.05 -seconds 1000 -cutoff 1000000 -solve -quit (default strategy 1)
ratioGap was changed from 0.05 to 0.05
String of -cutoff is illegalfor double parameter seconds value remains No matchfor 1000 -? for list of commands-1
No matchfor 1000000 -? for list of commands
Running single threaded is no problem, that is, |std::execution::seq|.
I was not able to readily track this down in the |CbcMain1| function, it
is a rather complicated function.
Anyone experienced this before?
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#332>, or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABWJYHCFARNBUZM6LB6TAD3SETTDDANCNFSM4Q6JEUSQ>.
|
@jjhforrest Ah, yes, any reason not to change |
Excellent. It seems to solve my problem. When I build static libs are there other defines I should remember to include when linking coin into my executable? |
Even if one disabled multithreading for Cbc you want Cbc to be thread-safe - always and everytime. |
Stefan,
I have no idea when that #ifdef appeared. I presume that whoever wrote
the code (which might be me years ago) was not sure if the code included
by the ifdef was correct and did not want to create any bugs.
John
…On 08/09/2020 16:11, Stefan Vigerske wrote:
@jjhforrest <https://github.com/jjhforrest> Ah, yes, any reason not
to change |CBC_THREAD_SAFE| to |CBC_THREAD| so that we get thread
safe code by default?
Even if one disabled multithreading for Cbc you want Cbc to be
thread-safe - always and everytime.
That is, I don't understand why there is an |ifdef| at all.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#332 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABWJYHEKXU7DI4MKE5L4ZALSEZCS7ANCNFSM4Q6JEUSQ>.
|
The stuff inside |
I am adding "CBC_THREAD",
"COIN_HAS_COINUTILS",
"COIN_HAS_OSI",
"COIN_HAS_CLP",
"COIN_HAS_CGL",
"COIN_HAS_CBC", as defines for now when linking against Cbc. Is there anything else I should add? |
If you're using the autotools, it shouldn't be necessary to define any of those symbols. The |
My /* src/config_cbc.h. Generated by configure. */
/* src/config_cbc.h.in. */
#ifndef CBC_VERSION
/* Version number of project */
#define CBC_VERSION "2.10"
/* Major Version number of project */
#define CBC_VERSION_MAJOR 2
/* Minor Version number of project */
#define CBC_VERSION_MINOR 10
/* Release Version number of project */
#define CBC_VERSION_RELEASE 9999
#endif When I search the headers of There is a lot of "#ifdef COIN_HAS_CLP" in other headers in I am not using autotools but cmake when linking coin to my own code. |
It's a sign for unclean code if the Cbc API header have |
So the Lines 1351 to 1354 in b127c88
and then the usage in e.g. Lines 1193 to 1204 in b127c88
This is not thread safe is it? Anyone can increment |
Embarrassing. Of course it was my compile definitions that got screwed up. |
I can confirm, that adding
And I guess as the cleanup in the |
The cleanup in the |
I am trying to run some MIP problems in parallel using the
CbcMain0/CbcMain1
pattern.I am on https://github.com/coin-or/Cbc/tree/stable/2.10
Problem is both on Linux and Windows.
My code snippet is
It fails when parsing the commandline parameters (I think) The output is like
Running single threaded is no problem, that is,
std::execution::seq
.I was not able to readily track this down in the
CbcMain1
function, it is a rather complicated function.Anyone experienced this before?
The text was updated successfully, but these errors were encountered: