Using GLPK in parallel_for loop

1.4k views Asked by At

I want to run the LP solver in GLPK in a parallel_for loop. The problems are all independent of each other so there shouldn't be any interference.

Here is an example code that fails, this is essentially the example code from the glpk wikibook but wrapped in a parallel_for loop. Any help will be appreciated

//#include <stdio.h>            /* C input/output                       */
//#include <stdlib.h>           /* C standard library                   */
#include <iostream>
#include <glpk.h>             /* GNU GLPK linear/mixed integer solver */
#include <ppl.h>

using namespace concurrency;
using namespace std;

void main()
{
    parallel_for(0, 10, [](int i){
        /* declare variables */
        glp_prob *lp;
    int *ia = new int[4];
    int *ja = new int[4];
    double *ar = new double[4];
    double z, x1, x2;


    /* create problem */
    lp = glp_create_prob();
    glp_set_prob_name(lp, "minimax");
    glp_set_obj_dir(lp, GLP_MAX);


    /* fill problem */
    glp_add_rows(lp, 2);
    //glp_set_row_name(lp, 1, "p");
    glp_set_row_bnds(lp, 1, GLP_UP, 0.0, 1.0);
    //glp_set_row_name(lp, 2, "q");
    glp_set_row_bnds(lp, 2, GLP_UP, 0.0, 2.0);


    glp_add_cols(lp, 2);
    //glp_set_col_name(lp, 1, "x1");
    glp_set_col_bnds(lp, 1, GLP_LO, 0.0, 0.0);
    glp_set_obj_coef(lp, 1, 0.6);
    //glp_set_col_name(lp, 2, "x2");
    glp_set_col_bnds(lp, 2, GLP_LO, 0.0, 0.0);
    glp_set_obj_coef(lp, 2, 0.5);


    ia[1] = 1, ja[1] = 1, ar[1] = 1.0; /* a[1,1] = 1 */
    ia[2] = 1, ja[2] = 2, ar[2] = 2.0; /* a[1,2] = 2 */
    ia[3] = 2, ja[3] = 1, ar[3] = 3.0; /* a[2,1] = 3 */
    ia[4] = 2, ja[4] = 2, ar[4] = 1.0; /* a[2,2] = 1 */
    glp_load_matrix(lp, 4, ia, ja, ar);



    /* solve problem */
    glp_simplex(lp, NULL);
    /* recover and display results */
    z = glp_get_obj_val(lp);
    x1 = glp_get_col_prim(lp, 1);
    x2 = glp_get_col_prim(lp, 2);
    printf("z = %g; x1 = %g; x2 = %g\n", z, x1, x2);
    /* housekeeping */
    glp_delete_prob(lp);
    glp_free_env();
});
    system("pause");
}
2

There are 2 answers

0
ActuariallyImpaired On BEST ANSWER

I have found the problem. The issue is with the GLPK source code, there are a couple of routines that are not reenterable causing some big issues. This is documented here: http://en.wikibooks.org/wiki/GLPK/Using_the_GLPK_callable_library . There is also a fix in place but it requires rebuilding it. Note that this only works with version 4.50 of GLPK and older, newer versions have a slightly different layout.

While Ben was completely correct, making this change to the library solves all issues and lets you free the environment inside the loop.

1
Ben Voigt On

You're calling glp_free_env from inside each thread, while the library is still actively doing work in other threads. That won't work well -- you're yanking the rug out from under threads working hard..

Instead call it only after all threads completed computation (join them). For this simple example, you can probably skip the cleanup step altogether.