Program listing for file numerics/src/tools/GAMSlink.h#
Return to documentation for this file
1#ifndef GAMSLINK_H
2#define GAMSLINK_H
3
4#include <stdbool.h>
5#include "NumericsMatrix.h"
6#include <assert.h>
7
8
9
10
11enum { GAMS_OPT_GENERAL, GAMS_OPT_SOLVER };
12
13typedef struct GAMS_opt_bool_ {
14 char* name;
15 bool value;
16 unsigned type;
17 struct GAMS_opt_bool_* next_opt;
18} GAMS_opt_bool;
19
20
21typedef struct GAMS_opt_int_ {
22 char* name;
23 int value;
24 unsigned type;
25 struct GAMS_opt_int_* next_opt;
26} GAMS_opt_int;
27
28
29typedef struct GAMS_opt_double_ {
30 char* name;
31 double value;
32 unsigned type;
33 struct GAMS_opt_double_* next_opt;
34} GAMS_opt_double;
35
36
37typedef struct GAMS_opt_str_ {
38 char* name;
39 char* value;
40 unsigned type;
41 struct GAMS_opt_str_* next_opt;
42} GAMS_opt_str;
43
44
45typedef struct {
46 char* model_dir;
47 char* gams_dir;
48 char* filename;
49 char* filename_suffix;
50 GAMS_opt_str* opt_str_list;
51 GAMS_opt_bool* opt_bool_list;
52 GAMS_opt_int* opt_int_list;
53 GAMS_opt_double* opt_double_list;
54} SN_GAMSparams;
55
56typedef struct SN_GAMS_NM_gdx_
57{
58 NumericsMatrix* mat;
59 char* name;
60 struct SN_GAMS_NM_gdx_* next;
61} SN_GAMS_NM_gdx;
62
63typedef struct SN_GAMS_NV_gdx_
64{
65 double* vec;
66 char* name;
67 unsigned size;
68 struct SN_GAMS_NV_gdx_* next;
69} SN_GAMS_NV_gdx;
70
71typedef struct
72{
73 SN_GAMS_NM_gdx* mat_for_gdx;
74 SN_GAMS_NV_gdx* vec_for_gdx;
75 SN_GAMS_NV_gdx* vec_from_gdx;
76} SN_GAMS_gdx;
77
78static inline const char* GAMSP_get_filename(const void* GP)
79{
80 return ((SN_GAMSparams*) GP)->filename;
81}
82
83static inline void GAMSP_set_filename(void* GP, char* filename)
84{
85 ((SN_GAMSparams*) GP)->filename = filename;
86}
87
88static inline const char* GAMSP_get_filename_suffix(const void* GP)
89{
90 return ((SN_GAMSparams*) GP)->filename_suffix;
91}
92
93static inline void GAMSP_set_filename_suffix(void* GP, char* filename_suffix)
94{
95 ((SN_GAMSparams*) GP)->filename_suffix = filename_suffix;
96}
97
98#define SN_FREE_TILL_NEXT(X, T, ELT) \
99 while(X) { T* next = X->next; X->ELT = NULL; X->name = NULL; X->next = NULL;\
100 free(X); X = next; }
101
102
103static inline void SN_free_SN_GAMS_gdx(SN_GAMS_gdx* gdx_data)
104{
105 assert(gdx_data);
106
107 SN_GAMS_NM_gdx* mat_for_gdx = gdx_data->mat_for_gdx;
108 SN_GAMS_NV_gdx* vec_for_gdx = gdx_data->vec_for_gdx;
109 SN_GAMS_NV_gdx* vec_from_gdx = gdx_data->vec_from_gdx;
110 SN_FREE_TILL_NEXT(mat_for_gdx, SN_GAMS_NM_gdx, mat);
111 SN_FREE_TILL_NEXT(vec_for_gdx, SN_GAMS_NV_gdx, vec);
112 SN_FREE_TILL_NEXT(vec_from_gdx, SN_GAMS_NV_gdx, vec);
113
114}
115
116
117static inline void SN_GAMS_add_NM_to_gdx(SN_GAMS_gdx* gdx_data, NumericsMatrix* M, char* name)
118{
119 assert(gdx_data);
120 assert(M);
121 assert(name);
122
123 SN_GAMS_NM_gdx* mat_for_gdx;
124
125 if (gdx_data->mat_for_gdx)
126 {
127 mat_for_gdx = gdx_data->mat_for_gdx;
128 while (mat_for_gdx->next)
129 {
130 mat_for_gdx = mat_for_gdx->next;
131 }
132 mat_for_gdx->next = (SN_GAMS_NM_gdx*)malloc(sizeof(SN_GAMS_NM_gdx));
133
134 mat_for_gdx = mat_for_gdx->next;
135 }
136 else
137 {
138 gdx_data->mat_for_gdx = (SN_GAMS_NM_gdx*)malloc(sizeof(SN_GAMS_NM_gdx));
139 mat_for_gdx = gdx_data->mat_for_gdx;
140 }
141
142 mat_for_gdx->mat = M;
143 mat_for_gdx->name = name;
144 mat_for_gdx->next = NULL;
145}
146
147#define SN_GAMS_ADD_GDX(X) \
148 SN_GAMS_NV_gdx* X; \
149 \
150 if (gdx_data->X) \
151 { \
152 X = gdx_data->X; \
153 while (X->next) \
154 { \
155 X = X->next; \
156 } \
157 X->next = (SN_GAMS_NV_gdx*)malloc(sizeof(SN_GAMS_NV_gdx)); \
158 \
159 X = X->next; \
160 } \
161 else \
162 { \
163 gdx_data->X = (SN_GAMS_NV_gdx*)malloc(sizeof(SN_GAMS_NV_gdx)); \
164 X = gdx_data->X; \
165 } \
166 \
167 X->vec = vec; \
168 X->name = name; \
169 X->size = size; \
170 X->next = NULL;
171
172static inline void SN_GAMS_add_NV_to_gdx(SN_GAMS_gdx* gdx_data, double* vec, char* name, unsigned size)
173{
174 assert(gdx_data);
175 assert(vec);
176 assert(name);
177
178 SN_GAMS_ADD_GDX(vec_for_gdx)
179}
180
181static inline void SN_GAMS_add_NV_from_gdx(SN_GAMS_gdx* gdx_data, double* vec, char* name, unsigned size)
182{
183 assert(gdx_data);
184 assert(vec);
185 assert(name);
186
187 SN_GAMS_ADD_GDX(vec_from_gdx)
188}
189
190#ifdef HAVE_GAMS_C_API
191
192#include <stdio.h>
193#include <string.h>
194#include <stdlib.h>
195
196#include "gamsxcc.h"
197#include "gclgms.h"
198#include "gevmcc.h"
199#include "gmomcc.h"
200#include "idxcc.h"
201#include "optcc.h"
202
203
204#define idxerror(i, s) { idxErrorStr(Xptr, i, msg, GMS_SSSIZE); \
205 printf("%s failed: %s\n",s,msg); return; }
206
207#define idxerrorR(i, s) { idxErrorStr(Xptr, i, msg, GMS_SSSIZE); \
208 printf("%s failed: %s\n",s,msg); return 1; }
209
210static inline const char* GAMSP_get_gams_dir(const void* GP)
211{
212 return ((SN_GAMSparams*) GP)->gams_dir;
213}
214
215static inline void GAMSP_set_gams_dir(void* GP, char* gams_dir)
216{
217 ((SN_GAMSparams*) GP)->gams_dir = gams_dir;
218}
219
220
221#define STR_VALUE(arg) #arg
222#define SPACE_CONC(str1,str2) str1 " " str2
223
224static inline void SN_Gams_set_dirs(const SN_GAMSparams* solverParameters, const char* defModel, const char* defGAMSdir, char* model, char* GAMSdir, char* model_file)
225{
226 assert(solverParameters);
227 assert(defModel);
228 assert(defGAMSdir);
229 assert(model);
230 assert(GAMSdir);
231 assert(model_file);
232
233 if (solverParameters->model_dir)
234 {
235 size_t len1 = strlen(solverParameters->model_dir);
236 strncpy(model, solverParameters->model_dir, len1);
237 strncpy(&model[len1], model_file, GMS_SSSIZE-len1-2);
238 model[GMS_SSSIZE-1] = '\0';
239 }
240 else
241 {
242 strncpy(model, defModel, GMS_SSSIZE-2);
243 model[GMS_SSSIZE-1] = '\0';
244 }
245
246 if (solverParameters->gams_dir)
247 {
248 strncpy(GAMSdir, solverParameters->gams_dir, GMS_SSSIZE-2);
249 GAMSdir[GMS_SSSIZE-1] = '\0';
250 }
251 else
252 {
253 strncpy(GAMSdir, defGAMSdir, GMS_SSSIZE-2);
254 GAMSdir[GMS_SSSIZE-1] = '\0';
255 }
256}
257
258#define WALK_GAMSP_OPTS(GAMSP_OPT_L, GAMSP_OPT_T, GAMS_OPT_FUN) \
259 if (GAMSP_OPT_L) \
260 { \
261 GAMSP_OPT_T* next_opt = GAMSP_OPT_L; \
262 do \
263 { \
264 GAMSP_OPT_T* opt = next_opt; \
265 next_opt = opt->next_opt; \
266 GAMS_OPT_FUN(Opts[opt->type], opt->name, opt->value); \
267 } \
268 while (next_opt); \
269 }
270
271static inline void SN_Gams_set_default(const SN_GAMSparams* GP, optHandle_t* Opts)
272{
273 assert(GP);
274 assert(Opts);
275 WALK_GAMSP_OPTS(GP->opt_str_list, GAMS_opt_str, optSetStrStr);
276 WALK_GAMSP_OPTS(GP->opt_bool_list, GAMS_opt_bool, optSetIntStr);
277 WALK_GAMSP_OPTS(GP->opt_int_list, GAMS_opt_int, optSetIntStr);
278 WALK_GAMSP_OPTS(GP->opt_double_list, GAMS_opt_double, optSetDblStr);
279}
280
281
282static inline int getGamsSolverOpt(const optHandle_t Optr, const char* sysdir, const char* solverDefName)
283{
284 assert(Optr);
285 assert(sysdir);
286 assert(solverDefName);
287
288 char deffile[GMS_SSSIZE];
289 char msg[GMS_SSSIZE];
290 strncpy(deffile, sysdir, sizeof(deffile));
291 strncat(deffile, "/opt", sizeof(deffile) - strlen(deffile) - 1);
292 strncat(deffile, solverDefName, sizeof(deffile) - strlen(deffile) - 1);
293 strncat(deffile, ".def", sizeof(deffile) - strlen(deffile) - 1);
294
295 if (optReadDefinition(Optr,deffile)) {
296 int itype;
297 for (int i=1; i<=optMessageCount(Optr); ++i) {
298 optGetMessage(Optr, i, msg, &itype);
299 printf("%s\n", msg);
300 }
301 return 1;
302 }
303 return 0;
304}
305static inline int getGamsOpt(const optHandle_t Optr, const char *sysdir)
306{
307 char msg[GMS_SSSIZE];
308 char deffile[GMS_SSSIZE];
309 strncpy(deffile, sysdir, sizeof(deffile));
310 strncat(deffile, "/optgams.def", sizeof(deffile) - strlen(deffile) - 1);
311
312 if (optReadDefinition(Optr,deffile)) {
313 int itype;
314 for (int i=1; i<=optMessageCount(Optr); ++i) {
315 optGetMessage(Optr, i, msg, &itype);
316 printf("%s\n", msg);
317 }
318 return 1;
319 }
320 optSetStrStr(Optr, "sysdir", sysdir);
321
322 return 0;
323}
324
325static inline int CallGams(const gamsxHandle_t Gptr, const optHandle_t Optr, const char *sysdir, const char *model)
326{
327 char msg[GMS_SSSIZE];
328
329 assert(Gptr); assert(Optr);
330
331 optSetStrStr(Optr, "input", model);
332 optSetIntStr(Optr, "logoption", 2);
333
334 optSetIntStr(Optr, "optfile", 1);
335
336
337 if (gamsxRunExecDLL(Gptr, Optr, sysdir, 1, msg)) {
338 printf ("Could not execute RunExecDLL: %s\n", msg);
339 return 1;
340 }
341
342 return 0;
343}
344
345static inline int iparam_to_GDX(idxHandle_t Xptr, const char* name, const char* descr, double param)
346{
347 char msg[GMS_SSSIZE];
348 int dim = 1;
349
350 if (idxDataWriteStart(Xptr, name, descr, 0, &dim, msg, GMS_SSSIZE) == 0)
351 idxerrorR(idxGetLastError(Xptr), "idxDataWriteStart");
352
353 idxDataWrite(Xptr, 0, param);
354
355 if (0==idxDataWriteDone(Xptr))
356 idxerrorR(idxGetLastError(Xptr), "idxDataWriteDone");
357
358 return 0;
359}
360
361
362static inline int NV_to_GDX(idxHandle_t Xptr, const char* name, const char* descr, const double* vector, unsigned size)
363{
364 char msg[GMS_SSSIZE];
365
366 int dim = size;
367 if (idxDataWriteStart(Xptr, name, descr, 1, &dim, msg, GMS_SSSIZE) == 0)
368 idxerrorR(idxGetLastError(Xptr), "idxDataWriteStart");
369
370 idxDataWriteDenseColMajor(Xptr, 1, vector);
371
372 if (0==idxDataWriteDone(Xptr))
373 idxerrorR(idxGetLastError(Xptr), "idxDataWriteDone");
374
375 return 0;
376}
377
378int NM_to_GDX(idxHandle_t Xptr, const char* name, const char* descr, NumericsMatrix* M);
379
380static inline int GDX_to_NV(idxHandle_t Xptr, const char* name, double* vector, unsigned size)
381{
382 char msg[GMS_SSSIZE];
383
384 int nbdims, nbelts;
385 int dims[GLOBAL_MAX_INDEX_DIM];
386 if (idxDataReadStart(Xptr, name, &nbdims, dims, &nbelts, msg, GMS_SSSIZE) == 0)
387 idxerrorR(idxGetLastError(Xptr), "idxDataReadStart");
388
389 if (nbdims != 1 || dims[0] != (int)size)
390 {
391 printf("GDX_to_NV :: inconsistency between expected size and actual one, variable %s\n", name);
392 printf("expected dimension: %d; actual one: %d\n", 1, nbdims);
393 printf("expected number of elements: %d; actual one: %d\n", size, nbelts);
394 }
395 idxDataReadDenseColMajor(Xptr, vector);
396
397 if (0==idxDataReadDone(Xptr))
398 idxerrorR(idxGetLastError(Xptr), "idxDataWriteDone");
399
400 return 0;
401}
402
403
404#if defined(__cplusplus) && !defined(BUILD_AS_CPP)
405extern "C"
406{
407#endif
408
409 int SN_gams_solve(unsigned iter, optHandle_t Optr, char* sysdir, char* model, const char* base_name, SolverOptions* options, SN_GAMS_gdx* gdx_data);
410
411 void filename_datafiles(const int iter, const int solverId, const char* base_name, unsigned len, char* template_name, char* log_filename);
412
413
414 SN_GAMSparams* createGAMSparams(char* model_dir, char* gams_dir);
415
416
417 void add_GAMS_opt_str(SN_GAMSparams* GP, char* name, char* value_orig, unsigned type);
418
419
420 void add_GAMS_opt_bool(SN_GAMSparams* GP, char* name, bool value, unsigned type);
421
422
423 void add_GAMS_opt_int(SN_GAMSparams* GP, char* name, int value, unsigned type);
424
425
426 void add_GAMS_opt_double(SN_GAMSparams* GP, char* name, double value, unsigned type);
427
428
429 void deleteGAMSparams(SN_GAMSparams* GP);
430
431#if defined(__cplusplus) && !defined(BUILD_AS_CPP)
432}
433#endif
434
435#else
436
437#endif
438
439#endif