Google OR-Tools v9.15
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
xpress_environment.cc
Go to the documentation of this file.
1// Copyright 2010-2025 Google LLC
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14// Initial version of this code was provided by RTE
15
17
18#include <cstdlib>
19// NOLINTNEXTLINE(build/c++17)
20#include <filesystem>
21#include <functional>
22#include <string>
23#include <vector>
24
25#include "absl/base/call_once.h"
26#include "absl/base/const_init.h"
27#include "absl/status/status.h"
28#include "absl/strings/str_cat.h"
29#include "absl/strings/str_join.h"
30#include "absl/synchronization/mutex.h"
34
35namespace operations_research {
36
37#define STRINGIFY2(X) #X
38#define STRINGIFY(X) STRINGIFY2(X)
39
40// Let's not reformat for rest of the file.
41// This was generated with the parse_header_xpress.py script.
42// See the comment at the top of the script.
43
44// This is the 'define' section.
45// NOLINTBEGIN(whitespace/line_length)
46// NOLINTBEGIN(google3-runtime-global-variables)
47// clang-format off
48std::function<int(XPRSprob* p_prob)> XPRScreateprob = nullptr;
49std::function<int(XPRSprob prob)> XPRSdestroyprob = nullptr;
50std::function<int(const char* path)> XPRSinit = nullptr;
51std::function<int(void)> XPRSfree = nullptr;
52std::function<int(char* buffer, int maxbytes)> XPRSgetlicerrmsg = nullptr;
53std::function<int(int* p_i, char* p_c)> XPRSlicense = nullptr;
54std::function<int(char* banner)> XPRSgetbanner = nullptr;
55std::function<int(char* version)> XPRSgetversion = nullptr;
56std::function<int(int *p_major, int *p_minor, int *p_build)> XPRSgetversionnumbers = nullptr;
57std::function<int(XPRSprob prob, const char* probname)> XPRSsetprobname = nullptr;
58std::function<int(XPRSprob prob, int control)> XPRSsetdefaultcontrol = nullptr;
59std::function<int(XPRSprob prob, int reason)> XPRSinterrupt = nullptr;
60std::function<int(XPRSprob prob, int control, int value)> XPRSsetintcontrol = nullptr;
61std::function<int(XPRSprob prob, int control, XPRSint64 value)> XPRSsetintcontrol64 = nullptr;
62std::function<int(XPRSprob prob, int control, double value)> XPRSsetdblcontrol = nullptr;
63std::function<int(XPRSprob prob, int control, const char* value)> XPRSsetstrcontrol = nullptr;
64std::function<int(XPRSprob prob, int objidx, int control, int value)> XPRSsetobjintcontrol = nullptr;
65std::function<int(XPRSprob prob, int objidx, int control, double value)> XPRSsetobjdblcontrol = nullptr;
66std::function<int(XPRSprob prob, int control, int* p_value)> XPRSgetintcontrol = nullptr;
67std::function<int(XPRSprob prob, int control, XPRSint64* p_value)> XPRSgetintcontrol64 = nullptr;
68std::function<int(XPRSprob prob, int control, double* p_value)> XPRSgetdblcontrol = nullptr;
69std::function<int(XPRSprob prob, int control, char* value, int maxbytes, int* p_nbytes)> XPRSgetstringcontrol = nullptr;
70std::function<int(XPRSprob prob, int attrib, int* p_value)> XPRSgetintattrib = nullptr;
71std::function<int(XPRSprob prob, int attrib, char* value, int maxbytes, int* p_nbytes)> XPRSgetstringattrib = nullptr;
72std::function<int(XPRSprob prob, int attrib, double* p_value)> XPRSgetdblattrib = nullptr;
73std::function<int(XPRSprob prob, int objidx, int attrib, double* p_value)> XPRSgetobjdblattrib = nullptr;
74std::function<int(XPRSprob prob, int objidx, const double solution[], double* p_objval)> XPRScalcobjn = nullptr;
75std::function<int(XPRSprob prob, const char* name, int* p_id, int* p_type)> XPRSgetcontrolinfo = nullptr;
76std::function<int(XPRSprob prob, double objcoef[], int first, int last)> XPRSgetobj = nullptr;
77std::function<int(XPRSprob prob, double rhs[], int first, int last)> XPRSgetrhs = nullptr;
78std::function<int(XPRSprob prob, double rng[], int first, int last)> XPRSgetrhsrange = nullptr;
79std::function<int(XPRSprob prob, double lb[], int first, int last)> XPRSgetlb = nullptr;
80std::function<int(XPRSprob prob, double ub[], int first, int last)> XPRSgetub = nullptr;
81std::function<int(XPRSprob prob, int row, int col, double* p_coef)> XPRSgetcoef = nullptr;
82std::function<int(XPRSprob prob, int* status, double x[], int first, int last)> XPRSgetsolution = nullptr;
83std::function<int(XPRSprob prob, int* status, double duals[], int first, int last)> XPRSgetduals = nullptr;
84std::function<int(XPRSprob prob, int* status, double djs[], int first, int last)> XPRSgetredcosts = nullptr;
85std::function<int(XPRSprob prob, int nrows, int ncoefs, const char rowtype[], const double rhs[], const double rng[], const int start[], const int colind[], const double rowcoef[])> XPRSaddrows = nullptr;
86std::function<int(XPRSprob prob, int nrows, int ncoefs, const char rowtype[], const double rhs[], const double rng[], const XPRSint64 start[], const int colind[], const double rowcoef[])> XPRSaddrows64 = nullptr;
87std::function<int(XPRSprob prob, int nrows, const int rowind[])> XPRSdelrows = nullptr;
88std::function<int(XPRSprob prob, int ncols, int ncoefs, const double objcoef[], const int start[], const int rowind[], const double rowcoef[], const double lb[], const double ub[])> XPRSaddcols = nullptr;
89std::function<int(XPRSprob prob, int ncols, const int colind[], const double objcoef[], int priority, double weight)> XPRSaddobj = nullptr;
90std::function<int(XPRSprob prob, int row, int ncoefs, const int rowqcol1[], int const rowqcol2[], const double rowqcoef[])> XPRSaddqmatrix64 = nullptr;
91std::function<int(XPRSprob prob, int type, const char names[], int first, int last)> XPRSaddnames = nullptr;
92std::function<int(XPRSprob prob, int type, char names[], int first, int last)> XPRSgetnames = nullptr;
93std::function<int(XPRSprob prob, int nsets, XPRSint64 nelems, const char settype[], const XPRSint64 start[], const int colind[], const double refval[])> XPRSaddsets64 = nullptr;
94std::function<int(XPRSprob prob, int ncols, const int colind[])> XPRSdelcols = nullptr;
95std::function<int(XPRSprob prob, int ncols, const int colind[], const char coltype[])> XPRSchgcoltype = nullptr;
96std::function<int(XPRSprob prob, const int rowstat[], const int colstat[])> XPRSloadbasis = nullptr;
97std::function<int(XPRSprob prob)> XPRSpostsolve = nullptr;
98std::function<int(XPRSprob prob, int objsense)> XPRSchgobjsense = nullptr;
99std::function<int(XPRSprob prob, char* errmsg)> XPRSgetlasterror = nullptr;
100std::function<int(XPRSprob prob, int rowstat[], int colstat[])> XPRSgetbasis = nullptr;
101std::function<int(XPRSprob prob, const char* filename, const char* flags)> XPRSwriteprob = nullptr;
102std::function<int(XPRSprob prob, const char* filename)> XPRSsaveas = nullptr;
103std::function<int(XPRSprob prob, char rowtype[], int first, int last)> XPRSgetrowtype = nullptr;
104std::function<int(XPRSprob prob, char coltype[], int first, int last)> XPRSgetcoltype = nullptr;
105std::function<int(XPRSprob prob, int nbounds, const int colind[], const char bndtype[], const double bndval[])> XPRSchgbounds = nullptr;
106std::function<int(XPRSprob prob, int length, const double solval[], const int colind[], const char* name)> XPRSaddmipsol = nullptr;
107std::function<int(XPRSprob prob, int nrows, const int rowind[])> XPRSloaddelayedrows = nullptr;
108std::function<int(XPRSprob prob, int nrows, const int rowind[], const int colind[], const int complement[])> XPRSsetindicators = nullptr;
109std::function<int(XPRSprob prob, int ndirs, const int colind[], const int priority[], const char dir[], const double uppseudo[], const double downpseudo[])> XPRSloaddirs;
110std::function<int(XPRSprob prob, double x[], double slack[], double duals[], double djs[])> XPRSgetlpsol = nullptr;
111std::function<int(XPRSprob prob, double x[], double slack[])> XPRSgetmipsol = nullptr;
112std::function<int(XPRSprob prob, int ncols, const int colind[], const double objcoef[])> XPRSchgobj = nullptr;
113std::function<int(XPRSprob prob, int row, int col, double coef)> XPRSchgcoef = nullptr;
114std::function<int(XPRSprob prob, int ncoefs, const int rowind[], const int colind[], const double rowcoef[])> XPRSchgmcoef = nullptr;
115std::function<int(XPRSprob prob, XPRSint64 ncoefs, const int rowind[], const int colind[], const double rowcoef[])> XPRSchgmcoef64 = nullptr;
116std::function<int(XPRSprob prob, int ncoefs, const int objqcol1[], const int objqcol2[], const double objqcoef[])> XPRSchgmqobj = nullptr;
117std::function<int(XPRSprob prob, int nrows, const int rowind[], const double rhs[])> XPRSchgrhs = nullptr;
118std::function<int(XPRSprob prob, int nrows, const int rowind[], const double rng[])> XPRSchgrhsrange = nullptr;
119std::function<int(XPRSprob prob, int nrows, const int rowind[], const char rowtype[])> XPRSchgrowtype = nullptr;
120std::function<int(XPRSprob prob, int objidx)> XPRSdelobj = nullptr;
121std::function<int(XPRSprob prob, void (XPRS_CC *f_intsol)(XPRSprob cbprob, void* cbdata), void* p, int priority)> XPRSaddcbintsol = nullptr;
122std::function<int(XPRSprob prob, void (XPRS_CC *f_intsol)(XPRSprob cbprob, void* cbdata), void* p)> XPRSremovecbintsol = nullptr;
123std::function<int(XPRSprob prob, void (XPRS_CC *f_message)(XPRSprob cbprob, void* cbdata, const char* msg, int msglen, int msgtype), void* p, int priority)> XPRSaddcbmessage = nullptr;
124std::function<int(XPRSprob prob, void (XPRS_CC *f_message)(XPRSprob cbprob, void* cbdata, const char* msg, int msglen, int msgtype), void* p)> XPRSremovecbmessage = nullptr;
125std::function<int(XPRSprob prob, int (XPRS_CC *f_checktime)(XPRSprob cbprob, void* cbdata), void* p, int priority)> XPRSaddcbchecktime = nullptr;
126std::function<int(XPRSprob prob, int (XPRS_CC *f_checktime)(XPRSprob cbprob, void* cbdata), void* p)> XPRSremovecbchecktime = nullptr;
127std::function<int(XPRSprob prob, const char* flags)> XPRSlpoptimize = nullptr;
128std::function<int(XPRSprob prob, const char* flags)> XPRSmipoptimize = nullptr;
129std::function<int(XPRSprob prob, const char* flags, int* solvestatus, int* solstatus)> XPRSoptimize = nullptr;
130// clang-format on
131// NOLINTEND(google3-runtime-global-variables)
132// NOLINTEND(whitespace/line_length)
133
134void LoadXpressFunctions(DynamicLibrary* xpress_dynamic_library) {
135 // This was generated with the parse_header_xpress.py script.
136 // See the comment at the top of the script.
137
138 // This is the 'assign' section.
139 // NOLINTBEGIN(whitespace/line_length)
140 // clang-format off
141 xpress_dynamic_library->GetFunction(&XPRScreateprob, "XPRScreateprob");
142 xpress_dynamic_library->GetFunction(&XPRSdestroyprob, "XPRSdestroyprob");
143 xpress_dynamic_library->GetFunction(&XPRSinit, "XPRSinit");
144 xpress_dynamic_library->GetFunction(&XPRSfree, "XPRSfree");
145 xpress_dynamic_library->GetFunction(&XPRSgetlicerrmsg, "XPRSgetlicerrmsg");
146 xpress_dynamic_library->GetFunction(&XPRSlicense, "XPRSlicense");
147 xpress_dynamic_library->GetFunction(&XPRSgetbanner, "XPRSgetbanner");
148 xpress_dynamic_library->GetFunction(&XPRSgetversion, "XPRSgetversion");
149 xpress_dynamic_library->GetFunction(&XPRSgetversionnumbers, "XPRSgetversionnumbers");
150 xpress_dynamic_library->GetFunction(&XPRSsetprobname, "XPRSsetprobname");
151 xpress_dynamic_library->GetFunction(&XPRSsetdefaultcontrol, "XPRSsetdefaultcontrol");
152 xpress_dynamic_library->GetFunction(&XPRSinterrupt, "XPRSinterrupt");
153 xpress_dynamic_library->GetFunction(&XPRSsetintcontrol, "XPRSsetintcontrol");
154 xpress_dynamic_library->GetFunction(&XPRSsetintcontrol64, "XPRSsetintcontrol64");
155 xpress_dynamic_library->GetFunction(&XPRSsetdblcontrol, "XPRSsetdblcontrol");
156 xpress_dynamic_library->GetFunction(&XPRSsetstrcontrol, "XPRSsetstrcontrol");
157 xpress_dynamic_library->GetFunction(&XPRSsetobjintcontrol, "XPRSsetobjintcontrol");
158 xpress_dynamic_library->GetFunction(&XPRSsetobjdblcontrol, "XPRSsetobjdblcontrol");
159 xpress_dynamic_library->GetFunction(&XPRSgetintcontrol, "XPRSgetintcontrol");
160 xpress_dynamic_library->GetFunction(&XPRSgetintcontrol64, "XPRSgetintcontrol64");
161 xpress_dynamic_library->GetFunction(&XPRSgetdblcontrol, "XPRSgetdblcontrol");
162 xpress_dynamic_library->GetFunction(&XPRSgetstringcontrol, "XPRSgetstringcontrol");
163 xpress_dynamic_library->GetFunction(&XPRSgetintattrib, "XPRSgetintattrib");
164 xpress_dynamic_library->GetFunction(&XPRSgetstringattrib, "XPRSgetstringattrib");
165 xpress_dynamic_library->GetFunction(&XPRSgetdblattrib, "XPRSgetdblattrib");
166 xpress_dynamic_library->GetFunction(&XPRSgetobjdblattrib, "XPRSgetobjdblattrib");
167 xpress_dynamic_library->GetFunction(&XPRScalcobjn, "XPRScalcobjn");
168 xpress_dynamic_library->GetFunction(&XPRSgetcontrolinfo, "XPRSgetcontrolinfo");
169 xpress_dynamic_library->GetFunction(&XPRSgetobj, "XPRSgetobj");
170 xpress_dynamic_library->GetFunction(&XPRSgetrhs, "XPRSgetrhs");
171 xpress_dynamic_library->GetFunction(&XPRSgetrhsrange, "XPRSgetrhsrange");
172 xpress_dynamic_library->GetFunction(&XPRSgetlb, "XPRSgetlb");
173 xpress_dynamic_library->GetFunction(&XPRSgetub, "XPRSgetub");
174 xpress_dynamic_library->GetFunction(&XPRSgetcoef, "XPRSgetcoef");
175 xpress_dynamic_library->GetFunction(&XPRSgetsolution, "XPRSgetsolution");
176 xpress_dynamic_library->GetFunction(&XPRSgetduals, "XPRSgetduals");
177 xpress_dynamic_library->GetFunction(&XPRSgetredcosts, "XPRSgetredcosts");
178 xpress_dynamic_library->GetFunction(&XPRSaddrows, "XPRSaddrows");
179 xpress_dynamic_library->GetFunction(&XPRSaddrows64, "XPRSaddrows64");
180 xpress_dynamic_library->GetFunction(&XPRSdelrows, "XPRSdelrows");
181 xpress_dynamic_library->GetFunction(&XPRSdelobj, "XPRSdelobj");
182 xpress_dynamic_library->GetFunction(&XPRSaddcols, "XPRSaddcols");
183 xpress_dynamic_library->GetFunction(&XPRSaddobj, "XPRSaddobj");
184 xpress_dynamic_library->GetFunction(&XPRSaddqmatrix64, "XPRSaddqmatrix64");
185 xpress_dynamic_library->GetFunction(&XPRSaddnames, "XPRSaddnames");
186 xpress_dynamic_library->GetFunction(&XPRSgetnames, "XPRSgetnames");
187 xpress_dynamic_library->GetFunction(&XPRSaddsets64, "XPRSaddsets64");
188 xpress_dynamic_library->GetFunction(&XPRSdelcols, "XPRSdelcols");
189 xpress_dynamic_library->GetFunction(&XPRSchgcoltype, "XPRSchgcoltype");
190 xpress_dynamic_library->GetFunction(&XPRSloadbasis, "XPRSloadbasis");
191 xpress_dynamic_library->GetFunction(&XPRSpostsolve, "XPRSpostsolve");
192 xpress_dynamic_library->GetFunction(&XPRSchgobjsense, "XPRSchgobjsense");
193 xpress_dynamic_library->GetFunction(&XPRSgetlasterror, "XPRSgetlasterror");
194 xpress_dynamic_library->GetFunction(&XPRSgetbasis, "XPRSgetbasis");
195 xpress_dynamic_library->GetFunction(&XPRSwriteprob, "XPRSwriteprob");
196 xpress_dynamic_library->GetFunction(&XPRSsaveas, "XPRSsaveas");
197 xpress_dynamic_library->GetFunction(&XPRSgetrowtype, "XPRSgetrowtype");
198 xpress_dynamic_library->GetFunction(&XPRSgetcoltype, "XPRSgetcoltype");
199 xpress_dynamic_library->GetFunction(&XPRSchgbounds, "XPRSchgbounds");
200 xpress_dynamic_library->GetFunction(&XPRSaddmipsol, "XPRSaddmipsol");
201 xpress_dynamic_library->GetFunction(&XPRSloaddelayedrows, "XPRSloaddelayedrows");
202 xpress_dynamic_library->GetFunction(&XPRSsetindicators, "XPRSsetindicators");
203 xpress_dynamic_library->GetFunction(&XPRSloaddirs, "XPRSloaddirs");
204 xpress_dynamic_library->GetFunction(&XPRSgetlpsol, "XPRSgetlpsol");
205 xpress_dynamic_library->GetFunction(&XPRSgetmipsol, "XPRSgetmipsol");
206 xpress_dynamic_library->GetFunction(&XPRSchgobj, "XPRSchgobj");
207 xpress_dynamic_library->GetFunction(&XPRSchgcoef, "XPRSchgcoef");
208 xpress_dynamic_library->GetFunction(&XPRSchgmcoef, "XPRSchgmcoef");
209 xpress_dynamic_library->GetFunction(&XPRSchgmcoef64, "XPRSchgmcoef64");
210 xpress_dynamic_library->GetFunction(&XPRSchgmqobj, "XPRSchgmqobj");
211 xpress_dynamic_library->GetFunction(&XPRSchgrhs, "XPRSchgrhs");
212 xpress_dynamic_library->GetFunction(&XPRSchgrhsrange, "XPRSchgrhsrange");
213 xpress_dynamic_library->GetFunction(&XPRSchgrowtype, "XPRSchgrowtype");
214 xpress_dynamic_library->GetFunction(&XPRSdelobj, "XPRSdelobj");
215 xpress_dynamic_library->GetFunction(&XPRSaddcbintsol, "XPRSaddcbintsol");
216 xpress_dynamic_library->GetFunction(&XPRSremovecbintsol, "XPRSremovecbintsol");
217 xpress_dynamic_library->GetFunction(&XPRSaddcbmessage, "XPRSaddcbmessage");
218 xpress_dynamic_library->GetFunction(&XPRSremovecbmessage, "XPRSremovecbmessage");
219 xpress_dynamic_library->GetFunction(&XPRSaddcbchecktime, "XPRSaddcbchecktime");
220 xpress_dynamic_library->GetFunction(&XPRSremovecbchecktime, "XPRSremovecbchecktime");
221 xpress_dynamic_library->GetFunction(&XPRSlpoptimize, "XPRSlpoptimize");
222 xpress_dynamic_library->GetFunction(&XPRSmipoptimize, "XPRSmipoptimize");
223 xpress_dynamic_library->GetFunction(&XPRSoptimize, "XPRSoptimize");
224 // clang-format on
225 // NOLINTEND(whitespace/line_length)
226}
227
228void printXpressBanner(bool error) {
229 char banner[XPRS_MAXBANNERLENGTH];
230 XPRSgetbanner(banner);
231
232 if (error) {
233 LOG(ERROR) << "XpressInterface : Xpress banner :\n" << banner << "\n";
234 } else {
235 LOG(WARNING) << "XpressInterface : Xpress banner :\n" << banner << "\n";
236 }
237}
238
239std::vector<std::string> XpressDynamicLibraryPotentialPaths() {
240 std::vector<std::string> potential_paths;
241
242 // Look for libraries pointed by XPRESSDIR first.
243 const char* xpressdir_from_env = getenv("XPRESSDIR");
244 if (xpressdir_from_env != nullptr) {
245 LOG(INFO) << "Environment variable XPRESSDIR = " << xpressdir_from_env;
246#if defined(_MSC_VER) // Windows
247 potential_paths.push_back(
248 absl::StrCat(xpressdir_from_env, "\\bin\\xprs.dll"));
249#elif defined(__APPLE__) // macOS
250 potential_paths.push_back(
251 absl::StrCat(xpressdir_from_env, "/lib/libxprs.dylib"));
252#elif defined(__GNUC__) // Linux
253 potential_paths.push_back(
254 absl::StrCat(xpressdir_from_env, "/lib/libxprs.so"));
255#else
256 LOG(ERROR) << "OS Not recognized by xpress_environment.cc."
257 << " You won't be able to use Xpress.";
258#endif
259 } else {
260 LOG(WARNING) << "Environment variable XPRESSDIR undefined.";
261 }
262
263 // Search for canonical places.
264#if defined(_MSC_VER) // Windows
265 potential_paths.push_back(absl::StrCat("C:\\xpressmp\\bin\\xprs.dll"));
266 potential_paths.push_back(
267 absl::StrCat("C:\\Program Files\\xpressmp\\bin\\xprs.dll"));
268#elif defined(__APPLE__) // macOS
269 potential_paths.push_back(
270 absl::StrCat("/Library/xpressmp/lib/libxprs.dylib"));
271#elif defined(__GNUC__) // Linux
272 potential_paths.push_back(absl::StrCat("/opt/xpressmp/lib/libxprs.so"));
273#else
274 LOG(ERROR) << "OS Not recognized by xpress_environment.cc."
275 << " You won't be able to use Xpress.";
276#endif
277 return potential_paths;
278}
279
280absl::Status LoadXpressDynamicLibrary(std::string& xpresspath) {
281 static std::string* xpress_lib_path = new std::string;
282 static absl::once_flag xpress_loading_done;
283 static absl::Status* xpress_load_status = new absl::Status;
284 static DynamicLibrary* xpress_library = new DynamicLibrary;
285 static absl::Mutex mutex(absl::kConstInit);
286
287 absl::MutexLock lock(mutex);
288
289 absl::call_once(xpress_loading_done, []() {
290 const std::vector<std::string> canonical_paths =
292 for (const std::string& path : canonical_paths) {
293 if (xpress_library->TryToLoad(path)) {
294 LOG(INFO) << "Found the Xpress library in " << path << ".";
295 xpress_lib_path->clear();
296 std::filesystem::path p(path);
297 p.remove_filename();
298 xpress_lib_path->append(p.string());
299 break;
300 }
301 }
302
303 if (xpress_library->LibraryIsLoaded()) {
304 LOG(INFO) << "Loading all Xpress functions";
305 LoadXpressFunctions(xpress_library);
306 // Make sure the library we just loaded is recent enough.
307 int major = -1, minor = -1, build = -1;
309 XPRSgetversionnumbers(&major, &minor, &build) != 0)
310 *xpress_load_status =
311 util::StatusBuilder(absl::StatusCode::kNotFound)
312 << "Xpress optimizer library too old, need at least version "
313 << XPVERSION;
314 else if (major < XPVERSION)
315 *xpress_load_status = util::StatusBuilder(absl::StatusCode::kNotFound)
316 << "Xpress optimizer library version " << major
317 << " too old, need at least version "
318 << XPVERSION;
319 else
320 *xpress_load_status = absl::OkStatus();
321 } else {
322 *xpress_load_status = absl::NotFoundError(
323 absl::StrCat("Could not find the Xpress shared library. Looked in: [",
324 absl::StrJoin(canonical_paths, "', '"),
325 "]. Please check environment variable XPRESSDIR"));
326 }
327 });
328 xpresspath.clear();
329 xpresspath.append(*xpress_lib_path);
330 return *xpress_load_status;
331}
332
334void log_full_license_error(int code, const std::string& xpress_lib_dir);
336bool initXpressEnv(bool verbose, int xpress_oem_license_key) {
337 std::string xpress_lib_dir;
338 absl::Status status = LoadXpressDynamicLibrary(xpress_lib_dir);
339 if (!status.ok()) {
340 LOG(WARNING) << status << "\n";
341 return false;
342 }
343
344 int code;
345 // if not an OEM key
346 if (xpress_oem_license_key == 0) {
347 if (verbose) {
349 }
350
351 code = XPRSinit(nullptr);
352
353 if (!code) {
354 // XPRSbanner informs about Xpress version, options and error messages
355 if (verbose) {
356 printXpressBanner(false);
357 char version[16];
358 XPRSgetversion(version);
359 LOG(WARNING) << "Optimizer version: " << version
360 << " (OR-Tools was compiled with version " << XPVERSION
361 << ").";
362 }
363 return true;
364 } else {
365 log_full_license_error(code, xpress_lib_dir);
366 return false;
367 }
368 } else {
369 // if OEM key
370 if (verbose) {
371 LOG(WARNING) << "XpressInterface : Initialising xpress-MP with OEM key "
372 << xpress_oem_license_key;
373 }
374
375 int nvalue = 0;
376 int ierr;
377 char slicmsg[256] = "";
378 char errmsg[256];
379
380 XPRSlicense(&nvalue, slicmsg);
381 if (verbose) {
382 DLOG(INFO) << "XpressInterface : First message from XPRSLicense : "
383 << slicmsg;
384 }
385
386 nvalue = xpress_oem_license_key - ((nvalue * nvalue) / 19);
387 ierr = XPRSlicense(&nvalue, slicmsg);
388
389 if (verbose) {
390 DLOG(INFO) << "XpressInterface : Second message from XPRSLicense : "
391 << slicmsg;
392 }
393 if (ierr == 16) {
394 if (verbose) {
395 DLOG(INFO)
396 << "XpressInterface : Optimizer development software detected";
397 }
398 } else if (ierr != 0) {
399 // get the license error message
400 XPRSgetlicerrmsg(errmsg, 256);
401
402 LOG(ERROR) << "XpressInterface : " << errmsg;
403 return false;
404 }
405
406 code = XPRSinit(nullptr);
407
408 if (!code) {
409 return true;
410 } else {
411 LOG(ERROR) << "XPRSinit returned code : " << code << "\n";
412 return false;
413 }
414 }
415}
416void log_full_license_error(int code, const std::string& xpress_lib_dir) {
417 LOG(WARNING) << "XpressInterface: Xpress found at " << xpress_lib_dir << "\n";
418 char errmsg[256];
419 XPRSgetlicerrmsg(errmsg, 256);
420
421 LOG(ERROR) << "XpressInterface : License error : " << errmsg
422 << " (XPRSinit returned code " << code << "). \n";
423 LOG(ERROR)
424 << "|_Your Xpress installation should have set the env var XPAUTH_PATH"
425 " to the full path of your licence file\n";
426}
428 LOG(WARNING)
429 << "XpressInterface : Initialising xpress-MP with default parameters";
430}
431
433 bool correctlyInstalled = initXpressEnv(false);
434 if (correctlyInstalled) {
435 XPRSfree();
436 }
437 return correctlyInstalled;
438}
439
440} // namespace operations_research
bool LibraryIsLoaded() const
std::function< T > GetFunction(const char *function_name)
bool TryToLoad(const absl::string_view library_name)
OR-Tools root namespace.
std::function< int(XPRSprob prob, int objidx)> XPRSdelobj
std::function< int(XPRSprob prob, void(XPRS_CC *f_intsol)(XPRSprob cbprob, void *cbdata), void *p, int priority)> XPRSaddcbintsol
std::function< int(XPRSprob prob, int(XPRS_CC *f_checktime)(XPRSprob cbprob, void *cbdata), void *p)> XPRSremovecbchecktime
std::function< int(XPRSprob prob, int control)> XPRSsetdefaultcontrol
std::function< int(XPRSprob prob, int nrows, const int rowind[], const char rowtype[])> XPRSchgrowtype
std::function< int(XPRSprob prob, int objidx, const double solution[], double *p_objval)> XPRScalcobjn
std::function< int(char *banner)> XPRSgetbanner
absl::Status LoadXpressDynamicLibrary(std::string &xpresspath)
std::function< int(XPRSprob prob, int(XPRS_CC *f_checktime)(XPRSprob cbprob, void *cbdata), void *p, int priority)> XPRSaddcbchecktime
std::function< int(XPRSprob prob, int nrows, const int rowind[])> XPRSloaddelayedrows
std::function< int(XPRSprob prob, char rowtype[], int first, int last)> XPRSgetrowtype
std::function< int(XPRSprob prob, int attrib, int *p_value)> XPRSgetintattrib
std::function< int(XPRSprob prob, int ndirs, const int colind[], const int priority[], const char dir[], const double uppseudo[], const double downpseudo[])> XPRSloaddirs
std::function< int(XPRSprob prob, int ncoefs, const int objqcol1[], const int objqcol2[], const double objqcoef[])> XPRSchgmqobj
std::function< int(XPRSprob prob, void(XPRS_CC *f_message)(XPRSprob cbprob, void *cbdata, const char *msg, int msglen, int msgtype), void *p)> XPRSremovecbmessage
std::function< int(XPRSprob prob, char coltype[], int first, int last)> XPRSgetcoltype
std::function< int(XPRSprob prob, int attrib, double *p_value)> XPRSgetdblattrib
std::function< int(XPRSprob prob, int *status, double djs[], int first, int last)> XPRSgetredcosts
std::function< int(XPRSprob prob, const char *filename, const char *flags)> XPRSwriteprob
std::function< int(XPRSprob prob, void(XPRS_CC *f_message)(XPRSprob cbprob, void *cbdata, const char *msg, int msglen, int msgtype), void *p, int priority)> XPRSaddcbmessage
std::function< int(XPRSprob prob, double rhs[], int first, int last)> XPRSgetrhs
Select next search node to expand Select next item_i to add this new search node to the search Generate a new search node where item_i is not in the knapsack Check validity of this new partial solution(using propagators) - If valid
bool initXpressEnv(bool verbose, int xpress_oem_license_key)
init XPRESS environment.
void LoadXpressFunctions(DynamicLibrary *xpress_dynamic_library)
std::function< int(XPRSprob prob, int length, const double solval[], const int colind[], const char *name)> XPRSaddmipsol
std::function< int(XPRSprob prob, double x[], double slack[])> XPRSgetmipsol
std::function< int(XPRSprob prob, int nbounds, const int colind[], const char bndtype[], const double bndval[])> XPRSchgbounds
std::function< int(XPRSprob prob, int row, int col, double *p_coef)> XPRSgetcoef
std::function< int(XPRSprob prob, const int rowstat[], const int colstat[])> XPRSloadbasis
std::function< int(XPRSprob prob, int row, int col, double coef)> XPRSchgcoef
std::function< int(XPRSprob prob, int nrows, const int rowind[])> XPRSdelrows
std::function< int(XPRSprob prob, int type, char names[], int first, int last)> XPRSgetnames
std::function< int(XPRSprob prob, int ncols, const int colind[])> XPRSdelcols
std::function< int(XPRSprob prob, int control, double *p_value)> XPRSgetdblcontrol
std::function< int(XPRSprob prob, int objidx, int control, int value)> XPRSsetobjintcontrol
std::function< int(XPRSprob prob, double lb[], int first, int last)> XPRSgetlb
std::function< int(XPRSprob prob, const char *flags, int *solvestatus, int *solstatus)> XPRSoptimize
std::function< int(XPRSprob prob, int control, int *p_value)> XPRSgetintcontrol
std::function< int(XPRSprob prob, void(XPRS_CC *f_intsol)(XPRSprob cbprob, void *cbdata), void *p)> XPRSremovecbintsol
std::function< int(XPRSprob prob, int ncols, const int colind[], const char coltype[])> XPRSchgcoltype
std::function< int(XPRSprob prob, int nrows, const int rowind[], const int colind[], const int complement[])> XPRSsetindicators
std::function< int(char *version)> XPRSgetversion
std::function< int(XPRSprob prob, const char *name, int *p_id, int *p_type)> XPRSgetcontrolinfo
std::function< int(XPRSprob prob, double x[], double slack[], double duals[], double djs[])> XPRSgetlpsol
std::function< int(XPRSprob prob, int control, XPRSint64 *p_value)> XPRSgetintcontrol64
std::function< int(XPRSprob prob)> XPRSpostsolve
std::function< int(XPRSprob prob, double objcoef[], int first, int last)> XPRSgetobj
std::function< int(XPRSprob prob, int nrows, const int rowind[], const double rng[])> XPRSchgrhsrange
std::function< int(XPRSprob prob, int type, const char names[], int first, int last)> XPRSaddnames
std::function< int(XPRSprob prob, int ncoefs, const int rowind[], const int colind[], const double rowcoef[])> XPRSchgmcoef
void log_full_license_error(int code, const std::string &xpress_lib_dir)
std::function< int(void)> XPRSfree
std::function< int(XPRSprob prob, int reason)> XPRSinterrupt
std::function< int(char *buffer, int maxbytes)> XPRSgetlicerrmsg
std::function< int(XPRSprob prob, const char *filename)> XPRSsaveas
std::function< int(XPRSprob prob, int nsets, XPRSint64 nelems, const char settype[], const XPRSint64 start[], const int colind[], const double refval[])> XPRSaddsets64
std::function< int(XPRSprob prob, int control, int value)> XPRSsetintcontrol
std::function< int(XPRSprob prob, int nrows, int ncoefs, const char rowtype[], const double rhs[], const double rng[], const int start[], const int colind[], const double rowcoef[])> XPRSaddrows
std::function< int(XPRSprob prob, char *errmsg)> XPRSgetlasterror
std::function< int(XPRSprob prob, int attrib, char *value, int maxbytes, int *p_nbytes)> XPRSgetstringattrib
std::function< int(XPRSprob prob)> XPRSdestroyprob
std::function< int(XPRSprob prob, int control, double value)> XPRSsetdblcontrol
std::function< int(XPRSprob prob, XPRSint64 ncoefs, const int rowind[], const int colind[], const double rowcoef[])> XPRSchgmcoef64
std::function< int(XPRSprob prob, int *status, double x[], int first, int last)> XPRSgetsolution
std::function< int(XPRSprob prob, double rng[], int first, int last)> XPRSgetrhsrange
std::function< int(XPRSprob prob, double ub[], int first, int last)> XPRSgetub
void printXpressBanner(bool error)
std::function< int(int *p_major, int *p_minor, int *p_build)> XPRSgetversionnumbers
std::function< int(int *p_i, char *p_c)> XPRSlicense
std::function< int(XPRSprob prob, int control, const char *value)> XPRSsetstrcontrol
std::function< int(XPRSprob prob, int ncols, int ncoefs, const double objcoef[], const int start[], const int rowind[], const double rowcoef[], const double lb[], const double ub[])> XPRSaddcols
std::function< int(XPRSprob prob, int control, char *value, int maxbytes, int *p_nbytes)> XPRSgetstringcontrol
std::function< int(XPRSprob prob, int row, int ncoefs, const int rowqcol1[], int const rowqcol2[], const double rowqcoef[])> XPRSaddqmatrix64
std::function< int(XPRSprob prob, int ncols, const int colind[], const double objcoef[], int priority, double weight)> XPRSaddobj
std::function< int(XPRSprob prob, const char *flags)> XPRSmipoptimize
std::function< int(XPRSprob prob, int nrows, int ncoefs, const char rowtype[], const double rhs[], const double rng[], const XPRSint64 start[], const int colind[], const double rowcoef[])> XPRSaddrows64
std::function< int(XPRSprob prob, int nrows, const int rowind[], const double rhs[])> XPRSchgrhs
std::function< int(XPRSprob prob, int objidx, int attrib, double *p_value)> XPRSgetobjdblattrib
std::function< int(XPRSprob prob, int objidx, int control, double value)> XPRSsetobjdblcontrol
std::function< int(XPRSprob prob, int ncols, const int colind[], const double objcoef[])> XPRSchgobj
std::function< int(XPRSprob prob, int *status, double duals[], int first, int last)> XPRSgetduals
std::vector< std::string > XpressDynamicLibraryPotentialPaths()
std::function< int(XPRSprob *p_prob)> XPRScreateprob
std::function< int(XPRSprob prob, const char *flags)> XPRSlpoptimize
std::function< int(XPRSprob prob, int control, XPRSint64 value)> XPRSsetintcontrol64
std::function< int(XPRSprob prob, int objsense)> XPRSchgobjsense
std::function< int(const char *path)> XPRSinit
std::function< int(XPRSprob prob, const char *probname)> XPRSsetprobname
std::function< int(XPRSprob prob, int rowstat[], int colstat[])> XPRSgetbasis
#define XPRS_MAXBANNERLENGTH
#define XPRSint64
struct xo_prob_struct * XPRSprob
#define XPVERSION
#define XPRS_CC