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

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