X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Flpp%2Flpp_gurobi.c;h=a87e6e1e16097867a4a2ee316d9ada81fcd06a03;hb=dcff73b2cc34378750e2cc1979a4b120e19767a9;hp=13c34c2b6bdaaa6d12c8d55580f806852b41b731;hpb=81bdcefbdf4fdd36e07e86b9f9b4d43112edbc1f;p=libfirm diff --git a/ir/lpp/lpp_gurobi.c b/ir/lpp/lpp_gurobi.c index 13c34c2b6..a87e6e1e1 100644 --- a/ir/lpp/lpp_gurobi.c +++ b/ir/lpp/lpp_gurobi.c @@ -28,6 +28,7 @@ #include #include +#include #include "obst.h" @@ -42,6 +43,7 @@ static char gurobi_var_encoding[4] = { 0, 0, GRB_CONTINUOUS, GRB_BINARY }; typedef struct _gurobi_t { lpp_t *lpp; GRBenv *env; + GRBenv *modelenv; GRBmodel *model; } gurobi_t; @@ -58,16 +60,33 @@ static gurobi_t *new_gurobi(lpp_t *lpp) gurobi_t *grb = XMALLOCZ(gurobi_t); grb->lpp = lpp; - error = GRBloadenv(&grb->env, NULL); + /* /tmp/firm_gurobi.log is a hack (see below) */ + error = GRBloadenv(&grb->env, "/tmp/firm_gurobi.log"); check_gurobi_error(grb, error); + /* Matze: do not set the FILE* for logging output. Because: + * a) the function is deprecated + * b) gurobi closes the FILE handle when it is done, which leads to + * very unexpected effects when you pass stdout or stderr as logging + * output. + * The only thing gurobi sanely supports is giving a string with a filename + * :-( ...so we use /tmp/firm_gurobi.log as a temporary measure... + */ +#if 0 error = GRBsetlogfile(grb->env, lpp->log); check_gurobi_error(grb, error); +#else + if (lpp->log != stdout && lpp->log != stderr) { + error = GRBsetintparam(grb->env, GRB_INT_PAR_OUTPUTFLAG, 0); + check_gurobi_error(grb, error); + } +#endif return grb; } static void free_gurobi(gurobi_t *grb) { + GRBfreemodel(grb->model); GRBfreeenv(grb->env); free(grb); } @@ -157,9 +176,10 @@ static void gurobi_construct(gurobi_t *grb) objsen, 0, obj, sense, rhs, matbeg, matcnt, matind, matval, lb, NULL, vartype, colname, rowname); check_gurobi_error(grb, error); + grb->modelenv = GRBgetenv(grb->model); obstack_free(&obst, NULL); - free_lpp_matrix(lpp); + lpp_free_matrix(lpp); } static void gurobi_solve(gurobi_t *grb) @@ -172,39 +192,21 @@ static void gurobi_solve(gurobi_t *grb) double *values; double iterations; - /* set performance parameters */ - // CPXsetintparam(grb->env, CPX_PARAM_MIPSTART, CPX_ON); - //CPXsetintparam(grb->env, CPX_PARAM_MIPORDTYPE, CPX_MIPORDER_COST); - /* output every search tree node */ - // CPXsetintparam(grb->env, CPX_PARAM_MIPINTERVAL, 1); - - /* experimental switches */ - // CPXsetintparam(grb->env, CPX_PARAM_VARSEL, CPX_VARSEL_STRONG); - // CPXsetdblparam(grb->env, CPX_PARAM_BTTOL, 1.0); - // CPXsetintparam(grb->env, CPX_PARAM_BRDIR, CPX_BRDIR_UP); - /* Set the time limit appropriately */ if(lpp->time_limit_secs > 0.0) { - error = GRBsetdblparam(grb->env, GRB_DBL_PAR_TIMELIMIT, lpp->time_limit_secs); + error = GRBsetdblparam(grb->modelenv, GRB_DBL_PAR_TIMELIMIT, lpp->time_limit_secs); check_gurobi_error(grb, error); } - /* - * If we have enough time, we instruct cplex to imply some - * of its higher order magic to pursue the best solution - */ - if(lpp->emphasis) { - /* not implemented */ - } - +#if 0 /* * If a bound of the objective function is supplied, * set it accordingly, dependign on minimization or maximization. */ if(lpp->set_bound) { - //panic("bound not implemented yet"); fprintf(stderr, "Warning: gurobi bound not implemented yet\n"); } +#endif /* solve */ error = GRBoptimize(grb->model); @@ -223,20 +225,26 @@ static void gurobi_solve(gurobi_t *grb) default: lpp->sol_state = lpp_feasible; break; } - /* get variable solution values */ - values = alloca(numcols * sizeof(*values)); - error = GRBgetdblattrarray(grb->model, GRB_DBL_ATTR_X, 0, numcols, values); - check_gurobi_error(grb, error); - for(i=0; ivars[1+i]->value = values[i]; - lpp->vars[1+i]->value_kind = lpp_value_solution; - } + if (lpp->sol_state >= lpp_feasible) { + /* get variable solution values */ + values = alloca(numcols * sizeof(*values)); + error = GRBgetdblattrarray(grb->model, GRB_DBL_ATTR_X, 0, numcols, + values); + check_gurobi_error(grb, error); + for(i=0; ivars[1+i]->value = values[i]; + lpp->vars[1+i]->value_kind = lpp_value_solution; + } - /* Get the value of the objective function. */ - error = GRBgetdblattr(grb->model, GRB_DBL_ATTR_OBJVAL, &lpp->objval); - check_gurobi_error(grb, error); - error = GRBgetdblattr(grb->model , GRB_DBL_ATTR_OBJBOUND, &lpp->best_bound); - check_gurobi_error(grb, error); + /* Get the value of the objective function. */ + error = GRBgetdblattr(grb->model, GRB_DBL_ATTR_OBJVAL, &lpp->objval); + check_gurobi_error(grb, error); + error = GRBgetdblattr(grb->model , GRB_DBL_ATTR_OBJBOUND, + &lpp->best_bound); + if (error != 0) { + lpp->best_bound = FP_NAN; + } + } /* get some statistics */ error = GRBgetdblattr(grb->model, GRB_DBL_ATTR_ITERCOUNT, &iterations);