1 /*  _______________________________________________________________________
2 
3     DAKOTA: Design Analysis Kit for Optimization and Terascale Applications
4     Copyright 2014-2020 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
5     This software is distributed under the GNU Lesser General Public License.
6     For more information, see the README file in the top Dakota directory.
7     _______________________________________________________________________ */
8 
9 //- Class:        Iterator
10 //- Description:  Dynamic library load manager for third-party solver packages.
11 //- Version: $Id$
12 
13 // NOTE:  THIS IS NOT ACTIVE CODE
14 //
15 // It is just a "buffer" to maintain a record of a commit that is no longer
16 // maintained.  Revs related to DLib management (in the mid-May 2010)
17 // were deemed inappropriate to add to the top of DakotaIterator.cpp from
18 // the perperspective of DAKOTA code design/modularity.  Therefore, the
19 // code has been de-activated and moved into this source file for posterity.
20 //
21 // Assuming we do want to maintain "DL LoadManagement" capabability, these
22 // typedefs/functions/"iterator" prototypes should be re-designed and
23 // implemented in a new component for DAKOTA (e.g. DynLoadLib Manager?).
24 
25 #include "dakota_system_defs.hpp"
26 #include "dakota_global_defs.hpp"
27 
28 /* WJB: re-enable dependencies class-wrappers only if necessary
29 #ifdef HAVE_DOT
30 #include "DOTOptimizer.hpp"
31 #endif
32 #ifdef HAVE_NLPQL
33 #include "NLPQLPOptimizer.hpp"
34 #endif
35 #ifdef HAVE_NPSOL
36 #include "NPSOLOptimizer.hpp"
37 #include "NLSSOLLeastSq.hpp"
38 #endif
39 // WJB: end of re-enable dependencies comment */
40 
41 #if(defined(HAVE_DOT) || defined(HAVE_JEGA) || defined(HAVE_NLPQL) ||               defined(HAVE_NPSOL))
42 
43 #ifdef DAKOTA_SHLIB
44 #undef DAKOTA_DYNLIB
45 
46 typedef void (*p_vf)(void);
47 
48 // WJB - ToDo: prefer function over macro
49 #ifdef _WIN32
50 #include "dakota_windows.h"
51 #define find_dlsym(a,b,c) (a = (p_vf)GetProcAddress((HINSTANCE)(b),c))
52 #define NO_DLERROR
53 #else
54 #include <dlfcn.h>
55 #define find_dlsym(a,b,c) (a = dlsym(b,c))
56 #undef NO_DLERROR
57 #endif
58 
59 
60 typedef struct Libentry
61 {
62   const char *name;
63   p_vf f;
64 } Libentry;
65 
66 typedef struct SharedLib
67 {
68   const char *libname;
69   size_t nentries;
70   Libentry *Entries;
71 } SharedLib;
72 
73 struct NIDR_KWlib;
74 extern "C" NIDR_KWlib *nidr_lib_record(void *, const char*);
75 extern "C" void *nidr_dlopen(const char*);
76 
77 
Lib_load(SharedLib * L,int k)78 static p_vf Lib_load(SharedLib *L, int k)
79 {
80   Libentry *e, *ee;
81   const char *lname;
82 
83   void* h = nidr_dlopen(lname = L->libname);
84   if (!h) {
85 #ifndef NO_DLERROR
86     if ((const char* s = dlerror()))
87       std::cerr << "Cannot open library \"" << lname << "\":\n\t" << s;
88     else
89 #endif
90       std::cerr << "Cannot open library \"" << lname << "\n";
91     std::exit(1);
92   }
93   nidr_lib_record(h, L->libname); // for cleanup (e.g., dlclose()) at endOf exec
94   e = L->Entries;
95   ee = e + L->nentries;
96 
97   for(ee = e + L->nentries; e < ee; ++e)
98     if (!find_dlsym(e->f, h, e->name)) {
99       std::cerr << "Could not find " << e->name << " in library "
100                 << lname << "\n";
101       std::exit(2);
102     }
103 
104   return L->Entries[k].f;
105 }
106 
107 
108 static Libentry
109   Dot_entries[] = { {"dot_"}, {"dot510_"} },
110   Npsol_entries[] = { {"npsol_"}, {"nlssol_"}, {"npoptn2_"} },
111   Nlpql_entries[] = { {"nlpqlp_"}, {"ql_"} };
112 
113 #define NumberOf(x) (sizeof(x)/sizeof(x[0]))
114 
115 static SharedLib
116   Dot_lib = { "libdot.dll", NumberOf(Dot_entries), Dot_entries },
117   Npsol_lib = { "libnpsol.dll", NumberOf(Npsol_entries), Npsol_entries },
118   Nlpql_lib = { "libnlpql.dll", NumberOf(Nlpql_entries), Nlpql_entries };
119 
120 
121 // WJB - Dakota C++ style: obtain prototypes from their respective header files
122 #define DOT F77_FUNC(dot,DOT)
123 #define DOT510 F77_FUNC(dot510,DOT510)
124 #define NPSOL F77_FUNC(npsol,NPSOL)
125 #define NLSSOL F77_FUNC(nlssol,NLSSOL)
126 // BMA (20160315): Changed to use Fortran 2003 ISO C bindings.
127 // The Fortran symbol will be lowercase with same name as if in C
128 //#define NPOPTN2 F77_FUNC(npoptn2,NPOPTN2)
129 #define NPOPTN2 npoptn2
130 #define NLPQLP F77_FUNC(nlpqlp,NLPQLP)
131 #define QL F77_FUNC(ql,QL)
132 
133 /* WJB - ToDo:  verify redeclaration of an existing function and REMOVE!
134 extern "C" void DOT(int *info, int *ngotoz, int *method,
135         int *iprint, int *ndv, int *ncon, double *x,
136         double *xl, double *xu, double *obj, int *minmax,
137         double *g, double *rprm, int *iprm, double *wk,
138         int *nrwk, int *iwk, int *nriwk)
139 {
140         typedef void (*DOT_t)(int *, int *, int *,
141                         int *, int *, int *, double *,
142                         double *, double *, double *, int *,
143                         double *, double *, int *, double *,
144                         int *, int *, int *);
145         DOT_t f;
146         if (!(f = (DOT_t)Dot_entries[0].f))
147                 f = (DOT_t)Lib_load(&Dot_lib, 0);
148         f(info, ngotoz, method, iprint, ndv, ncon, x, xl, xu, obj,
149           minmax, g, rprm, iprm, wk, nrwk, iwk, nriwk);
150 }
151 
152 extern "C" void DOT510(int *ndv, int *ncon, int *ncola,  int *method, int *nrwk,
153         int *nriwk, int *nrb, int *ngmax, double *xl, double *xu)
154 {
155         typedef void (*DOT510_t)(int *, int *, int *,  int *, int *, int *,
156                                 int *, int *, double *, double *);
157         DOT510_t f;
158         if (!(f = (DOT510_t)Dot_entries[1].f))
159                 f = (DOT510_t)Lib_load(&Dot_lib, 1);
160         f(ndv, ncon, ncola,  method, nrwk, nriwk, nrb, ngmax, xl, xu);
161 }
162 
163 extern "C" void NPSOL(int *n, int *nclin, int *ncnln,
164         int *lda, int *ldju, int *ldr, double *a, double *bl, double *bu,
165         p_vf funcon, p_vf funobj, int *inform,  int *iter, int *istate,
166         double *c, double *cjacu, double *clamda, double *objf,
167         double *gradu, double *r, double *x, int *iw, int *leniw,
168         double *w, int *lenw)
169 {
170         typedef void (*NPSOL_t)(int *, int *, int *, int *, int *,
171                         int *, double *, double *, double *, p_vf, p_vf,
172                         int *, int *, int *, double *, double *, double *,
173                         double *, double *, double *, double *, int *,
174                         int *, double *, int *);
175         NPSOL_t f;
176         if (!(f = (NPSOL_t)Npsol_entries[0].f))
177                 f = (NPSOL_t)Lib_load(&Npsol_lib, 0);
178         f(n, nclin, ncnln, lda, ldju, ldr, a, bl, bu, funcon, funobj,
179           inform, iter, istate, c, cjacu, clamda, objf, gradu, r, x,
180           iw, leniw, w, lenw);
181 }
182 
183 extern "C" void NLSSOL(int *m, int *n, int *nclin, int *ncnln, int *lda,
184         int *ldcju, int *ldfju, int *ldr, double *a, double *bl, double *bu,
185         p_vf funcon, p_vf funobj, int *inform, int *iter, int *istate,
186         double *c, double *cjacu, double *y, double *f, double *fjacu,
187         double *clamda, double *objf, double *r, double *x, int *iw,
188         int *leniw, double *w, int *lenw)
189 {
190         typedef void (*NLSSOL_t)(int *, int *, int *, int *, int *, int *,
191                 int *, int *, double *, double *, double *, p_vf, p_vf,
192                 int *, int *, int *, double *, double *, double *,
193                 double *, double *, double *, double *, double *,
194                 double *, int *, int *, double *, int *);
195         NLSSOL_t F;
196         if (!(F = (NLSSOL_t)Npsol_entries[1].f))
197                 F = (NLSSOL_t)Lib_load(&Npsol_lib, 1);
198         F(m, n, nclin, ncnln, lda, ldcju, ldfju, ldr, a, bl, bu,
199           funcon, funobj, inform, iter, istate, c, cjacu, y, f,
200           fjacu, clamda, objf, r, x, iw, leniw, w, lenw);
201 }
202 
203 extern "C" void NPOPTN2(char *string, size_t string_len)
204 {
205         typedef void (*NPOPTN2_t)(char *, size_t);
206         NPOPTN2_t f;
207         if (!(f = (NPOPTN2_t)Npsol_entries[2].f))
208                 f = (NPOPTN2_t)Lib_load(&Npsol_lib, 2);
209         f(string, string_len);
210 }
211 
212 
213 extern "C" void NLPQLP(int *l, int *m, int *me, int *mmax, int *n, int *nmax, in
214 t *mnn2,
215         double *x, double *f, double *g, double *df, double *dg, double *u,
216         double *xl, double *xu, double *c, double *d, double *acc,
217         double *accqp, double *stpmin, int *maxfun, int *maxit, int *max_nm,
218         double *tol_nm, int *iprint, int *mode, int *iout, int *ifail,
219         double *wa, int *lwa, int *kwa, int *lkwa, int *active,
220         int *lactiv, int *lql, p_vf qpsolve)
221 {
222         typedef void (*NLPQLP_t)(int *, int *, int *, int *, int *, int *,
223                         int *mnn2, double *, double *, double *, double *,
224                         double *, double *, double *, double *, double *,                               double *, double *, double *, double *, int *, int *,
225                         int *, double *, int *, int *, int *, int *, double *,
226                         int *, int *, int *, int *, int *, int *, p_vf);
227         NLPQLP_t F;
228         if (!(F = (NLPQLP_t)Nlpql_entries[0].f))
229                 F = (NLPQLP_t)Lib_load(&Nlpql_lib, 0);
230         F(l, m, me, mmax, n, nmax, mnn2, x, f, g, df, dg, u, xl, xu, c, d, acc,
231           accqp, stpmin, maxfun, maxit, max_nm, tol_nm, iprint, mode, iout,
232           ifail, wa, lwa, kwa, lkwa, active, lactiv, lql, qpsolve);
233 }
234 
235 extern "C" void QL(int *m, int *me, int *mmax, int *n, int *nmax, int *mnn,
236    double *c, double *d, double *a, double *b, double *xl, double *xu,double *x,
237    double *u, double *eps, int *mode, int *iout, int *ifail, int *iprint,
238    double *war, int *lwar, int *iwar, int *liwar)
239 {
240         typedef void (*QL_t)(int *, int *, int *, int *, int *, int *,
241                         double *, double *, double *, double *, double *,
242                         double *, double *, double *, double *, int *, int *,
243                         int *, int *, double *, int *, int *, int *);
244         QL_t f;
245         if (!(f = (QL_t)Nlpql_entries[1].f))
246                 f = (QL_t)Lib_load(&Nlpql_lib, 1);
247         f(m, me, mmax, n, nmax, mnn, c, d, a, b, xl, xu, x, u, eps, mode,
248          iout, ifail, iprint, war, lwar, iwar, liwar);
249 }
250 // WJB: end of long ToDo verify redeclaration comment block */
251 
252 #endif // DAKOTA_SHLIB
253 #endif // HAVE_DOT or NPSOL or JEGA or NPPQL
254 
255