/[ascend]/trunk/ascend/solver/conopt_dl.c
ViewVC logotype

Contents of /trunk/ascend/solver/conopt_dl.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3306 - (show annotations) (download) (as text)
Tue Jan 2 02:04:43 2018 UTC (5 months, 3 weeks ago) by jpye
File MIME type: text/x-csrc
File size: 10072 byte(s)
add solver_conopt.conopttest to leaky-but-passing tests.
refine the debug output from CONOPT a little.

1 /* ASCEND modelling environment
2 Copyright (C) 2006, 2007 Carnegie Mellon University
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *//**
17 @file
18 This file allows CONOPT to be dlopened at runtime.
19 *//*
20 By John Pye
21 Based on conopt.c by Vicente Rico Ramirez (created 05/97)
22 */
23
24 #include <ascend/utilities/config.h>
25 #include <ascend/general/platform.h>
26 #include <ascend/utilities/error.h>
27 #include <ascend/utilities/ascEnvVar.h>
28 #include <ascend/general/env.h>
29 #include "conopt_dl.h"
30
31 #ifndef ASC_WITH_CONOPT
32 #ifdef __GNUC__
33 # warning "Shouldn't compile this file unless ASC_WITH_CONOPT set"
34 #endif
35 #else
36
37 #ifndef ASC_LINKED_CONOPT
38 # include <ctype.h>
39 # include <ascend/general/ascMalloc.h>
40 # include <ascend/utilities/ascDynaLoad.h>
41
42 //#define ASC_CONOPT_DEBUG
43 #ifdef ASC_CONOPT_DEBUG
44 # define MSG(...) CONSOLE_DEBUG(__VA_ARGS__)
45 #else
46 # define MSG(...) (void)0
47 #endif
48
49 /*------------------------------------------------------------------------------
50 DLOPENING CONOPT SUPPORT FUNCTIONS
51 */
52
53 # define INTINT (int*cntvect,int*v)
54 # define INTINT1 (cntvect,v)
55 # define INTDOUBLE (int*cntvect,double*v)
56 # define INTDOUBLE1 (cntvect,v)
57 # define SEMICOLON ;
58 # define SPACE
59
60 /*
61 Typedefs for the various function pointers
62 */
63 # define FN_TYPE_DECL(T,A,V,L) \
64 typedef int COI_CALL (T##_fn_t) A
65
66 CONOPT_FNS(FN_TYPE_DECL,SEMICOLON);
67 # undef FN_TYPE_DECL
68
69 /*
70 Define a struct to hold all the function pointers, then
71 declare it as a global variable.
72 */
73 # define FN_PTR_DECL(T,A,V,L) \
74 T##_fn_t* T##_ptr
75
76 typedef struct{
77 CONOPT_FNS(FN_PTR_DECL,SEMICOLON);
78 } conopt_fptrs_t;
79 # undef FN_PTR_DECL
80
81 conopt_fptrs_t conopt_fptrs;
82
83
84 /*
85 Declare local functions to hook into the DLL
86 */
87 # define FN_PTR_EXEC(T,A,V,L) \
88 int COI_CALL T A{ \
89 if(conopt_fptrs.T##_ptr==NULL){ \
90 return 1; \
91 } \
92 return (* conopt_fptrs.T##_ptr) V ; \
93 }
94
95 CONOPT_FNS(FN_PTR_EXEC,SPACE)
96
97 # undef FN_PTR_EXEC
98
99 /**
100 This function will load the DLL and resolve all the required symbols
101 */
102 int asc_conopt_load(){
103 # ifdef ASC_LINKED_CONOPT
104 # error "We don't use this if we've got linked CONOPT!"
105 # endif
106 static int loaded=0;
107 char *libpath;
108 int status;
109 char fnsymbol[400], *c;
110 const char *libname=ASC_CONOPT_LIB;
111 const char *envvar;
112
113 if(loaded) {
114 return 0; /* already loaded */
115 }
116
117 /* MSG("LOADING CONOPT..."); */
118
119 envvar = ASC_CONOPT_ENVVAR;
120
121 /* need to import this variable into the ascend 'environment' */
122 if(-1!=env_import(ASC_CONOPT_ENVVAR,getenv,Asc_PutEnv)){
123 MSG("Searching in path '%s' (from env var '%s')",getenv(envvar),envvar);
124 }/*else{
125 MSG("Default conopt search path: %s", ASC_CONOPT_DLPATH);
126 }*/
127
128 /** @TODO replace with a direct call to ospath and/or importhandler? */
129 libpath = SearchArchiveLibraryPath(libname, ASC_CONOPT_DLPATH, envvar);
130
131 if(libpath==NULL){
132 ERROR_REPORTER_NOLINE(ASC_PROG_ERR
133 , "Library '%s' could not be located (check value of env var '%s' and/or default path '%s')"
134 , libname, envvar, ASC_CONOPT_DLPATH
135 );
136 return 1;
137 }
138
139 status = Asc_DynamicLoad(libpath, NULL);
140 if (status != 0) {
141 ASC_FREE(libpath);
142 return 1; /* failed to load */
143 }
144
145 # if defined(FNAME_UCASE_NODECOR) || defined(FNAME_UCASE_DECOR) || defined(FNAME_UCASE_PREDECOR)
146 # define FNCASE(C) C=toupper(C)
147 # elif defined(FNAME_LCASE_NODECOR) || defined(FNAME_LCASE_DECOR)
148 # define FNCASE(C) C=tolower(C)
149 # else
150 # error "CONOPT case rule not defined"
151 # endif
152
153 # if defined(FNAME_UCASE_DECOR) || defined(FNAME_LCASE_DECOR)
154 # define FNDECOR(S,L) strcat(S,"_")
155 # elif defined(FNAME_UCASE_PREDECOR) /* on windows, precede with _ and append @L (integer value of L) */
156 # define FNDECOR(S,L) strcat(S,L);for(c=S+strlen(S)+1;c>S;--c){*c=*(c-1);} *S='_';
157 # else
158 # define FNDECOR(S,L) (void)0
159 # endif
160
161 # define FN_PTR_GET(T,A,V,L) \
162 sprintf(fnsymbol,"%s",#T); \
163 for(c=fnsymbol;*c!='\0';++c){ \
164 FNCASE(*c); \
165 } \
166 FNDECOR(fnsymbol,L); \
167 conopt_fptrs.T##_ptr = (T##_fn_t *)Asc_DynamicFunction(libpath,fnsymbol); \
168 if(conopt_fptrs.T##_ptr==NULL)status+=1;
169
170 CONOPT_FNS(FN_PTR_GET,SPACE)
171
172 # undef FN_PTR_GET
173 # undef FNDECOR
174 # undef FNCASE
175
176 ASC_FREE(libpath);
177
178 if(status!=0){
179 return 1; /* failed to resolve all symbols */
180 }
181
182 loaded = 1;
183 return 0;
184 }
185
186 #endif
187
188 /*-----------------------------------------------------------------------------
189 std.c (modified from the version provided with CONOPT)
190
191 This file has some 'standard' implementations for the mandatory
192 callback routines Message, ErrMsg, Status, and Solution.
193 The routines use global file pointers, so they are only intended
194 as examples that can be used for further refinements.
195
196 FIXME this code could probably be moved to asc_conopt.c?
197 */
198
199 #define MAXLINE 133 /* maximum line length plus an extra character
200 for the null terminator */
201
202 int COI_CALL asc_conopt_progress( int* LEN_INT, int* INT
203 , int* LEN_RL, double* RL, double* X, double* USRMEM
204 ){
205 MSG("Iteration %d, phase %d: %d infeasible, %d non-optimal; objective = %e"
206 , INT[0], INT[1], INT[2], INT[3], RL[1]
207 );
208 /* FIXME: NEED TO IMPLEMENT SOME KIND OF CALLBACK TO THE SOLVERREPORTER */
209 return 0;
210 }
211
212 int COI_CALL asc_conopt_message( int* SMSG, int* DMSG, int* NMSG, int* LLEN
213 ,double* USRMEM, char* MSGV, int MSGLEN
214 ){
215 /* This implementation is writing the screen file to stdout
216 the documentation file to a file opened in main with the name
217 document.txt and the status file to a file with the name
218 status.txt. */
219 int i,j,k,l;
220 char line[MAXLINE];
221 k = 0;
222 for( i=0; i<*SMSG;i++ ){
223 j = LLEN[i];
224 for( l= 0; l<j; l++ ) line[l] = MSGV[k+l];
225 line[j] = '\0';
226 MSG("%s", line);
227 k += MSGLEN;
228 }
229 /* k = 0;
230 for( i=0; i<*DMSG;i++ ){
231 j = LLEN[i];
232 for( l= 0; l<j; l++ ) line[l] = MSGV[k+l];
233 line[j] = '\0';
234 ERROR_REPORTER_NOLINE(ASC_PROG_NOTE,"%s\n", line);
235 k += MSGLEN;
236 }
237 */
238 k = 0;
239 for( i=0; i<*NMSG;i++ ){
240 j = LLEN[i];
241 for( l= 0; l<j; l++ ) line[l] = MSGV[k+l];
242 line[j] = '\0';
243 ERROR_REPORTER_NOLINE(ASC_USER_NOTE,"(CONOPT) %s", line);
244 k += MSGLEN;
245 }
246 return 0;
247 }
248
249 int COI_CALL asc_conopt_errmsg( int* ROWNO, int* COLNO, int* POSNO, int* MSGLEN
250 , double* USRMEM, char* MSG, int LENMSG
251 ){
252 /* Standard ErrMsg routine. Write to Documentation and Status file*/
253 int j,l;
254 char line[MAXLINE];
255 ERROR_REPORTER_START_NOLINE(ASC_PROG_ERR);
256 if ( *ROWNO == -1 ) {
257 FPRINTF(ASCERR,"Variable %d : ",*COLNO); }
258 else if ( *COLNO == -1 ) {
259 FPRINTF(ASCERR,"Equation %d : ",*ROWNO); }
260 else {
261 FPRINTF(ASCERR,"Variable %d appearing in Equation %d : ",*COLNO, *ROWNO); }
262 j = *MSGLEN;
263 for( l= 0; l<j; l++ ) line[l] = MSG[l];
264 line[j] = '\0';
265 FPRINTF(ASCERR,"%s\n", line);
266 error_reporter_end_flush();
267 return 0;
268 }
269
270 int COI_CALL asc_conopt_status(int* MODSTA, int* SOLSTA
271 , int* ITER, double* OBJVAL, double* USRMEM
272 ){
273 /* Standard Status routine. Write to all files */
274 MSG("CONOPT has finished Optimizing");
275 MSG("Model status = %8d", *MODSTA);
276 MSG("Solver status = %8d", *SOLSTA);
277 MSG("Iteration count = %8d", *ITER);
278 MSG("Objective value = %10f", *OBJVAL);
279
280 const char *modsta;
281 error_severity_t t = ASC_USER_SUCCESS;
282 switch(*MODSTA){
283 case 1: modsta = "optimal"; break;
284 case 2: modsta = "locally optimal"; break;
285 case 3: t = ASC_USER_ERROR; modsta = "unbounded"; break;
286 case 4: t = ASC_USER_ERROR; modsta = "infeasible"; break;
287 case 5: modsta = "locally infeasible"; break;
288 case 6: modsta = "intermediate infeasible"; break;
289 case 7: modsta = "intermediate non-optimal"; break;
290 case 12: modsta = "unknown type of error"; break;
291 case 13: modsta = "error no solution"; break;
292 case 15: modsta = "solved unique"; break;
293 case 16: modsta = "solved"; break;
294 case 17: modsta = "solved singular"; break;
295 default: t = ASC_PROG_ERR; modsta = "UNKNOWN MODSTA";
296 }
297 const char *solsta;
298 switch(*SOLSTA){
299 case 1: solsta = "normal completion"; break;
300 case 2: t = ASC_USER_NOTE; solsta = "iteration interrupted"; break;
301 case 3: t = ASC_PROG_NOTE; solsta = "time limit exceeded"; break;
302 case 4: t = ASC_PROG_ERR; solsta = "failed (terminated by solver)"; break;
303 case 5: t = ASC_PROG_ERR; solsta = "Error evaluation limit"; break;
304 case 8: t = ASC_USER_NOTE; solsta = "User interrupt"; break;
305 case 9: t = ASC_PROG_ERR; solsta = "Error: setup failure"; break;
306 case 10:t = ASC_PROG_ERR; solsta = "Error: solver failure"; break;
307 case 11:t = ASC_PROG_ERR; solsta = "Error: internal solver error"; break;
308 case 15:t = ASC_PROG_ERR; solsta = "Terminated by Quick Mode"; break;
309 default: t = ASC_PROG_ERR; solsta = "UNKNOWN SOLSTA";
310 }
311
312 MSG("CONOPT %s (%d): %s (%d)", solsta, *SOLSTA, modsta, *MODSTA);
313 ERROR_REPORTER_NOLINE(t,"CONOPT %s: %s", solsta, modsta);
314
315 return 0;
316 }
317
318 int COI_CALL asc_conopt_solution( double* XVAL, double* XMAR, int* XBAS
319 , int* XSTA, double* YVAL, double* YMAR, int* YBAS, int* YSTA
320 , int* N, int* M, double* USRMEM
321 ){
322 /* Standard Solution routine */
323 int i;
324 char *status[4] = {"Lower","Upper","Basic","Super"};
325 FILE *fd = stderr;
326
327 fprintf(fd,"\n Variable Solution value Reduced cost Status\n\n");
328 for ( i=0; i<*N; i++ )
329 fprintf(fd,"%6d%18f%18f%10s\n", i, XVAL[i], XMAR[i], status[XBAS[i]] );
330 fprintf(fd,"\n Constrnt Activity level Marginal cost Status\n\n");
331 for ( i=0; i<*M; i++ )
332 fprintf(fd,"%6d%18f%18f%10s\n", i, YVAL[i], YMAR[i], status[YBAS[i]] );
333
334 return 0;
335 }
336
337 #endif /* ASC_WITH_CONOPT */

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22