I wrote a C++ Mex file to call the CPLEX API. It works if I just use one thread, but if I use more than one thread I get "segmentation fault (core dumped)".
But the core dump does not happen for every size of matrix, just if A is 64x1024 and B is 63x2014 (or larger, I did not test it for every size)
Before trying with my Mex file, I stored the problem as .sav and .lp file and used the CPLEX interactive mode and it worked well. So there must be some problem in my code, but I don't get it. The Mex function takes 3 arguments (A,b,G).
Hope that anyone could tell me the mistake in my code. Or give me a hint how to figure out what is going wrong.
The linear system should look like:
min sum zp(i)+zm(i) s.t. A x = b and Gx-zp+zm = 0;
My attempted Mex code is:
#include <iostream>
#include <math.h>
#include <vector>
#include <algorithm>
#include "mex.h"
#include "mat.h"
#include "matrix.h"
#include <ilcplex/ilocplex.h>
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
IloEnv env;
IloModel model(env);
int n = mxGetN(prhs[0]);
int m = mxGetM(prhs[0]);
int p = mxGetM(prhs[2]);
IloNumVarArray x = IloNumVarArray(env,n,0,2,IloNumVar::Int);
IloNumVarArray zp = IloNumVarArray(env,p,0,IloInfinity,IloNumVar::Float);
IloNumVarArray zm = IloNumVarArray(env,p,0,IloInfinity,IloNumVar::Float);
x.setNames("x"); zp.setNames("zp"); zm.setNames("zm");
model.add(x); model.add(zp); model.add(zm);
//sum_i zp(i)+zm(i)
IloObjective obj = IloMinimize(env);
for(int i=0;i<zp.getSize();i++){
obj.setLinearCoef(zp[i],1);
obj.setLinearCoef(zm[i],1);
}
model.add(obj);
double *A = mxGetPr(prhs[0]);
double *b = mxGetPr(prhs[1]);
double *G = mxGetPr(prhs[2]);
{ //Ax=b
IloRangeArray cs = IloRangeArray(env);
for(int i=0;i<m;++i){
IloRange c(env,b[i],b[i]);
for( int j=0;j<n;++j){
c.setLinearCoef(x[j],A[j*m+i]);
}
cs.add(c);
}
model.add(cs);
}
{ //Gx-zp+zm=0
IloRangeArray cs = IloRangeArray(env);
for(int i=0;i<p;++i){
IloRange c(env,0,0);
for( int j=0;j<n;++j){
c.setLinearCoef(x[j],G[j*p+i]);
}
c.setLinearCoef(zp[i],-1);
c.setLinearCoef(zm[i],1);
cs.add(c);
}
model.add(cs);
}
IloCplex cpx(model);
cpx.exportModel("test.lp");
cpx.exportModel("test.sav");
IloCplex::ParameterSet cpxParam = cpx.getParameterSet();
cpxParam.setParam(IloCplex::MIPDisplay,3);
cpxParam.setParam(IloCplex::TiLim,5);
cpxParam.setParam(IloCplex::Threads,13);
cpxParam.setParam(IloCplex::BoolParam::CloneLog,false);
cpx.setParameterSet(cpxParam);
cpx.solve();
env.end();
}