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");
}
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.