Solving several problems concurrently with multithreaded application and XPRESS solver

258 Views Asked by At

I am trying to convert a single threaded application that uses Fico Xpress solver to have it solve several problems concurrently with OpenMP. The licensing method that I am using is limited to 1 process, so a multithreaded program should theorically work.

For each thread, I would need the program to:

  1. Execute a model
  2. Extract the problem
  3. Solve the problem

However, I keep getting segfaults and errors like the following:

Mosel: E-84: File `mem:0x7f5c9a0ca640/2000/0x7f5c9a0ca5c0': model cannot be renamed.
Mosel: E-83: Bim file `mem:0x7f5c9a0ca640/2000/0x7f5c9a0ca5c0' cannot be loaded.

For example, I took this sample code.

  1. Ran it without any modification and it works.
  2. Add a for(int i = 0; i < 100; i++), and it works, single threaded.
  3. Paralelize using #pragma omp parallel for and the "model cannot be renamed" error comes up.
  4. Add a #pragma omp critical inside the parallel for (for testing purposes) like the following, and it works.
    int main(){
        #pragma omp parallel for
        for (int i = 0; i < 100; i++){
        #pragma omp critical
           {
         ... variables and code ...
           } // end critical
        } // end for
    }

I could not get any samples to work after making them multithreaded, so it appears to be either a limitation of the solver, license or the way that I am using it. I am using a dongle license.

I am aware that Xpress has a certain support for multithreaded MIP search for a single problem, but I am interested in concurrent single threaded searches.

1

There are 1 best solutions below

0
On

I suspect this is the same problem as discussed here. In that discussion it turned out that XPRMloadmod() was used in a loop to load the per-iteration model. That function was called with the wrong arguments which resulted in different models with the same name, hence the error about renaming the model.

In order to get this going it is mandatory to call XPRMloadmod() with an internal name of "*", see the reference documentation here.

The code should look something like this (error checking omitted for brevity):

XPRMinit();
#pragma omp parallel for
for (int k = 0; k < 20; k++){
  XPRMmodel mod;
  int result;
  mod=XPRMloadmod("burglar4.bim", "*");
  XPRMrunmod(mod, &result, NULL);
}

Then of course add error checking to the code so that you don't end up using a model that was not properly loaded etc.