comparison libinterp/dldfcn/__glpk__.cc @ 21090:93d294511277

don't use setjmp/longjmp to handle error in glpk * __glpk__.cc (glpk, F__glpk__): Don't use setjmp/longjmp for non-local exit from glpk. Eliminate volatile from local variable declarations.
author John W. Eaton <jwe@octave.org>
date Fri, 15 Jan 2016 15:13:28 -0500
parents 4484384a2959
children 72eefc36c6b7
comparison
equal deleted inserted replaced
21089:2d7f658daa58 21090:93d294511277
24 #ifdef HAVE_CONFIG_H 24 #ifdef HAVE_CONFIG_H
25 #include <config.h> 25 #include <config.h>
26 #endif 26 #endif
27 27
28 #include <cfloat> 28 #include <cfloat>
29 #include <csetjmp>
30 #include <ctime> 29 #include <ctime>
31 30
32 #include "lo-ieee.h" 31 #include "lo-ieee.h"
33 32
34 #include "defun-dld.h" 33 #include "defun-dld.h"
69 double objul; 68 double objul;
70 double tolint; 69 double tolint;
71 double tolobj; 70 double tolobj;
72 }; 71 };
73 72
74 static jmp_buf mark; // Address for long jump to jump to
75
76 int 73 int
77 glpk (int sense, int n, int m, double *c, int nz, int *rn, int *cn, 74 glpk (int sense, int n, int m, double *c, int nz, int *rn, int *cn,
78 double *a, double *b, char *ctype, int *freeLB, double *lb, 75 double *a, double *b, char *ctype, int *freeLB, double *lb,
79 int *freeUB, double *ub, int *vartype, int isMIP, int lpsolver, 76 int *freeUB, double *ub, int *vartype, int isMIP, int lpsolver,
80 int save_pb, int scale, const control_params *par, 77 int save_pb, int scale, const control_params *par,
166 glp_load_matrix (lp, nz, rn, cn, a); 163 glp_load_matrix (lp, nz, rn, cn, a);
167 164
168 if (save_pb) 165 if (save_pb)
169 { 166 {
170 static char tmp[] = "outpb.lp"; 167 static char tmp[] = "outpb.lp";
171 if (glp_write_lp (lp, NULL, tmp) != 0) 168 if (glp_write_lp (lp, 0, tmp) != 0)
172 { 169 error ("__glpk__: unable to write problem");
173 // FIXME: This doesn't work anymore now that error does not return.
174 // Should longjmp just be deleted?
175 error ("__glpk__: unable to write problem");
176 longjmp (mark, -1);
177 }
178 } 170 }
179 171
180 // scale the problem data 172 // scale the problem data
181 if (! par->presol || lpsolver != 1) 173 if (! par->presol || lpsolver != 1)
182 glp_scale_prob (lp, scale); 174 glp_scale_prob (lp, scale);
340 // FIXME: Should we even need checking for an internal function? 332 // FIXME: Should we even need checking for an internal function?
341 if (args.length () != 9) 333 if (args.length () != 9)
342 print_usage (); 334 print_usage ();
343 335
344 // 1nd Input. A column array containing the objective function coefficients. 336 // 1nd Input. A column array containing the objective function coefficients.
345 volatile int mrowsc = args(0).rows (); 337 int mrowsc = args(0).rows ();
346 338
347 Matrix C = args(0).xmatrix_value ("__glpk__: invalid value of C"); 339 Matrix C = args(0).xmatrix_value ("__glpk__: invalid value of C");
348 340
349 double *c = C.fortran_vec (); 341 double *c = C.fortran_vec ();
350 Array<int> rn; 342 Array<int> rn;
351 Array<int> cn; 343 Array<int> cn;
352 ColumnVector a; 344 ColumnVector a;
353 volatile int mrowsA; 345 int mrowsA;
354 volatile int nz = 0; 346 int nz = 0;
355 347
356 // 2nd Input. A matrix containing the constraints coefficients. 348 // 2nd Input. A matrix containing the constraints coefficients.
357 // If matrix A is NOT a sparse matrix 349 // If matrix A is NOT a sparse matrix
358 if (args(1).is_sparse_type ()) 350 if (args(1).is_sparse_type ())
359 { 351 {
460 452
461 // 7th Input. A column array containing the types of the variables. 453 // 7th Input. A column array containing the types of the variables.
462 charMatrix VTYPE = args(6).char_matrix_value ("__glpk__: invalid value of VARTYPE"); 454 charMatrix VTYPE = args(6).char_matrix_value ("__glpk__: invalid value of VARTYPE");
463 455
464 Array<int> vartype (dim_vector (mrowsc, 1)); 456 Array<int> vartype (dim_vector (mrowsc, 1));
465 volatile int isMIP = 0; 457 int isMIP = 0;
466 for (int i = 0; i < mrowsc ; i++) 458 for (int i = 0; i < mrowsc ; i++)
467 { 459 {
468 if (VTYPE(i,0) == 'I') 460 if (VTYPE(i,0) == 'I')
469 { 461 {
470 isMIP = 1; 462 isMIP = 1;
473 else 465 else
474 vartype(i) = GLP_CV; 466 vartype(i) = GLP_CV;
475 } 467 }
476 468
477 // 8th Input. Sense of optimization. 469 // 8th Input. Sense of optimization.
478 volatile int sense; 470 int sense;
479 double SENSE = args(7).scalar_value ("__glpk__: invalid value of SENSE"); 471 double SENSE = args(7).xscalar_value ("__glpk__: invalid value of SENSE");
480 472
481 if (SENSE >= 0) 473 if (SENSE >= 0)
482 sense = 1; 474 sense = 1;
483 else 475 else
484 sense = -1; 476 sense = -1;
495 OCTAVE_GLPK_GET_INT_PARAM ("msglev", par.msglev); 487 OCTAVE_GLPK_GET_INT_PARAM ("msglev", par.msglev);
496 if (par.msglev < 0 || par.msglev > 3) 488 if (par.msglev < 0 || par.msglev > 3)
497 error ("__glpk__: PARAM.msglev must be 0 (no output) or 1 (error and warning messages only [default]) or 2 (normal output) or 3 (full output)"); 489 error ("__glpk__: PARAM.msglev must be 0 (no output) or 1 (error and warning messages only [default]) or 2 (normal output) or 3 (full output)");
498 490
499 // scaling option 491 // scaling option
500 volatile int scale = 16; 492 int scale = 16;
501 OCTAVE_GLPK_GET_INT_PARAM ("scale", scale); 493 OCTAVE_GLPK_GET_INT_PARAM ("scale", scale);
502 if (scale < 0 || scale > 128) 494 if (scale < 0 || scale > 128)
503 error ("__glpk__: PARAM.scale must either be 128 (automatic selection of scaling options), or a bitwise or of: 1 (geometric mean scaling), 16 (equilibration scaling), 32 (round scale factors to power of two), 64 (skip if problem is well scaled"); 495 error ("__glpk__: PARAM.scale must either be 128 (automatic selection of scaling options), or a bitwise or of: 1 (geometric mean scaling), 16 (equilibration scaling), 32 (round scale factors to power of two), 64 (skip if problem is well scaled");
504 496
505 // Dual simplex option 497 // Dual simplex option
539 OCTAVE_GLPK_GET_INT_PARAM ("presol", par.presol); 531 OCTAVE_GLPK_GET_INT_PARAM ("presol", par.presol);
540 if (par.presol < 0 || par.presol > 1) 532 if (par.presol < 0 || par.presol > 1)
541 error ("__glpk__: PARAM.presol must be 0 (do NOT use LP presolver) or 1 (use LP presolver [default])"); 533 error ("__glpk__: PARAM.presol must be 0 (do NOT use LP presolver) or 1 (use LP presolver [default])");
542 534
543 // LPsolver option 535 // LPsolver option
544 volatile int lpsolver = 1; 536 int lpsolver = 1;
545 OCTAVE_GLPK_GET_INT_PARAM ("lpsolver", lpsolver); 537 OCTAVE_GLPK_GET_INT_PARAM ("lpsolver", lpsolver);
546 if (lpsolver < 1 || lpsolver > 2) 538 if (lpsolver < 1 || lpsolver > 2)
547 error ("__glpk__: PARAM.lpsolver must be 1 (simplex method) or 2 (interior point method)"); 539 error ("__glpk__: PARAM.lpsolver must be 1 (simplex method) or 2 (interior point method)");
548 540
549 // Ratio test option 541 // Ratio test option
557 549
558 par.outdly = 0; 550 par.outdly = 0;
559 OCTAVE_GLPK_GET_INT_PARAM ("outdly", par.outdly); 551 OCTAVE_GLPK_GET_INT_PARAM ("outdly", par.outdly);
560 552
561 // Save option 553 // Save option
562 volatile int save_pb = 0; 554 int save_pb = 0;
563 OCTAVE_GLPK_GET_INT_PARAM ("save", save_pb); 555 OCTAVE_GLPK_GET_INT_PARAM ("save", save_pb);
564 save_pb = save_pb != 0; 556 save_pb = save_pb != 0;
565 557
566 // Real parameters 558 // Real parameters
567 559
597 double fmin = octave_NA; 589 double fmin = octave_NA;
598 ColumnVector lambda (mrowsA, octave_NA); 590 ColumnVector lambda (mrowsA, octave_NA);
599 ColumnVector redcosts (mrowsc, octave_NA); 591 ColumnVector redcosts (mrowsc, octave_NA);
600 double time; 592 double time;
601 int status; 593 int status;
602 volatile int errnum = 0; 594
603 595 int errnum = glpk (sense, mrowsc, mrowsA, c, nz, rn.fortran_vec (),
604 int jmpret = setjmp (mark); 596 cn.fortran_vec (), a.fortran_vec (), b, ctype,
605 597 freeLB.fortran_vec (), lb, freeUB.fortran_vec (), ub,
606 if (jmpret == 0) 598 vartype.fortran_vec (), isMIP, lpsolver, save_pb, scale,
607 errnum = glpk (sense, mrowsc, mrowsA, c, nz, rn.fortran_vec (), 599 &par, xmin.fortran_vec (), &fmin, &status,
608 cn.fortran_vec (), a.fortran_vec (), b, ctype, 600 lambda.fortran_vec (), redcosts.fortran_vec (), &time);
609 freeLB.fortran_vec (), lb, freeUB.fortran_vec (), ub,
610 vartype.fortran_vec (), isMIP, lpsolver, save_pb, scale,
611 &par, xmin.fortran_vec (), &fmin, &status,
612 lambda.fortran_vec (), redcosts.fortran_vec (), &time);
613 601
614 octave_scalar_map extra; 602 octave_scalar_map extra;
615 603
616 if (! isMIP) 604 if (! isMIP)
617 { 605 {