Skip to content

Commit b56ec14

Browse files
authored
Merge pull request #4667 from rte-france/xpress/better_performance
MPSolver-XPRESS: Remove superfluous calls to XPRSloadlp and XPRScreateprob
2 parents 29fabd9 + 2b792c0 commit b56ec14

4 files changed

Lines changed: 32 additions & 24 deletions

File tree

ortools/linear_solver/xpress_interface.cc

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <memory>
2222
#include <mutex>
2323
#include <string>
24+
#include <numeric>
2425

2526
#include "absl/strings/str_format.h"
2627
#include "ortools/base/logging.h"
@@ -844,7 +845,6 @@ XpressInterface::XpressInterface(MPSolver* const solver, bool mip)
844845
CHECK_STATUS(status);
845846
DCHECK(mLp != nullptr); // should not be NULL if status=0
846847
int nReturn = XPRSaddcbmessage(mLp, optimizermsg, (void*)this, 0);
847-
CHECK_STATUS(XPRSloadlp(mLp, "newProb", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
848848
CHECK_STATUS(
849849
XPRSchgobjsense(mLp, maximize_ ? XPRS_OBJ_MAXIMIZE : XPRS_OBJ_MINIMIZE));
850850
}
@@ -875,20 +875,15 @@ std::string XpressInterface::SolverVersion() const {
875875
// ------ Model modifications and extraction -----
876876

877877
void XpressInterface::Reset() {
878-
// Instead of explicitly clearing all modeling objects we
879-
// just delete the problem object and allocate a new one.
880-
CHECK_STATUS(XPRSdestroyprob(mLp));
881-
882-
int status;
883-
status = XPRScreateprob(&mLp);
884-
CHECK_STATUS(status);
885-
DCHECK(mLp != nullptr); // should not be NULL if status=0
886-
int nReturn = XPRSaddcbmessage(mLp, optimizermsg, (void*)this, 0);
887-
CHECK_STATUS(XPRSloadlp(mLp, "newProb", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
888-
889-
CHECK_STATUS(
890-
XPRSchgobjsense(mLp, maximize_ ? XPRS_OBJ_MAXIMIZE : XPRS_OBJ_MINIMIZE));
891-
878+
int nRows = getnumrows(mLp);
879+
std::vector<int> rows(nRows);
880+
std::iota(rows.begin(), rows.end(), 0);
881+
int nCols = getnumcols(mLp);
882+
std::vector<int> cols(nCols);
883+
std::iota(cols.begin(), cols.end(), 0);
884+
XPRSdelrows(mLp, nRows, rows.data());
885+
XPRSdelcols(mLp, nCols, cols.data());
886+
XPRSdelobj(mLp, 0);
892887
ResetExtractionInformation();
893888
mCstat.clear();
894889
mRstat.clear();
@@ -985,8 +980,7 @@ void XpressInterface::MakeRhs(double lb, double ub, double& rhs, char& sense,
985980
<< (ub - std::abs(ub - lb)) << "]";
986981
}
987982
rhs = ub;
988-
range = std::abs(
989-
ub - lb); // This happens implicitly by XPRSaddrows() and XPRSloadlp()
983+
range = std::abs(ub - lb); // This happens implicitly by XPRSaddrows()
990984
sense = 'R';
991985
} else if (ub < XPRS_PLUSINFINITY || (std::abs(ub) == XPRS_PLUSINFINITY &&
992986
std::abs(lb) > XPRS_PLUSINFINITY)) {

ortools/linear_solver/xpress_interface_test.cc

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,15 @@ class XPRSGetter {
155155
return value;
156156
}
157157

158+
std::string getStringAttribute(int attrib) {
159+
std::string value(280, '\0');
160+
int valueSize;
161+
EXPECT_STATUS(XPRSgetstringattrib(prob(), attrib, &value[0], value.size(),
162+
&valueSize));
163+
value.resize(valueSize - 1);
164+
return value;
165+
}
166+
158167
private:
159168
MPSolver* solver_;
160169

@@ -400,12 +409,16 @@ TEST_F(XpressFixtureMIP, Reset) {
400409
solver.MakeBoolVar("x1");
401410
solver.MakeBoolVar("x2");
402411
solver.MakeRowConstraint(12., 100.0);
412+
solver.MutableObjective()->SetMaximization();
403413
solver.Solve();
404414
EXPECT_EQ(getter.getNumConstraints(), 1);
405415
EXPECT_EQ(getter.getNumVariables(), 2);
416+
auto oldProbUuid = getter.getStringAttribute(XPRS_UUID);
406417
solver.Reset();
418+
EXPECT_EQ(getter.getStringAttribute(XPRS_UUID), oldProbUuid);
407419
EXPECT_EQ(getter.getNumConstraints(), 0);
408420
EXPECT_EQ(getter.getNumVariables(), 0);
421+
EXPECT_EQ(getter.getObjectiveSense(), XPRS_OBJ_MAXIMIZE);
409422
}
410423

411424
TEST_F(XpressFixtureMIP, MakeIntVar) {
@@ -737,7 +750,7 @@ TEST_F(XpressFixtureMIP, Write) {
737750
// disable formatting to keep the expected MPS readable
738751
// clang-format off
739752
std::string expectedMps = std::string("") +
740-
"NAME newProb" + "\n" +
753+
"NAME " + "\n" +
741754
"OBJSENSE MAXIMIZE" + "\n" +
742755
"ROWS" + "\n" +
743756
" N __OBJ___ " + "\n" +

ortools/xpress/environment.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,9 @@ std::function<int(XPRSprob prob, int control, XPRSint64* p_value)> XPRSgetintcon
6565
std::function<int(XPRSprob prob, int control, double* p_value)> XPRSgetdblcontrol = nullptr;
6666
std::function<int(XPRSprob prob, int control, char* value, int maxbytes, int* p_nbytes)> XPRSgetstringcontrol = nullptr;
6767
std::function<int(XPRSprob prob, int attrib, int* p_value)> XPRSgetintattrib = nullptr;
68+
std::function<int(XPRSprob prob, int attrib, char* value, int maxbytes, int* p_nbytes)> XPRSgetstringattrib = nullptr;
6869
std::function<int(XPRSprob prob, int attrib, double* p_value)> XPRSgetdblattrib = nullptr;
6970
std::function<int(XPRSprob prob, const char* name, int* p_id, int* p_type)> XPRSgetcontrolinfo = nullptr;
70-
std::function<int(XPRSprob prob, const char* probname, int ncols, int nrows, const char rowtype[], const double rhs[], const double rng[], const double objcoef[], const int start[], const int collen[], const int rowind[], const double rowcoef[], const double lb[], const double ub[])> XPRSloadlp = nullptr;
71-
std::function<int(XPRSprob prob, const char* probname, int ncols, int nrows, const char rowtype[], const double rhs[], const double rng[], const double objcoef[], const XPRSint64 start[], const int collen[], const int rowind[], const double rowcoef[], const double lb[], const double ub[])> XPRSloadlp64 = nullptr;
7271
std::function<int(XPRSprob prob, double objcoef[], int first, int last)> XPRSgetobj = nullptr;
7372
std::function<int(XPRSprob prob, double rhs[], int first, int last)> XPRSgetrhs = nullptr;
7473
std::function<int(XPRSprob prob, double rng[], int first, int last)> XPRSgetrhsrange = nullptr;
@@ -104,6 +103,7 @@ std::function<int(XPRSprob prob, int ncoefs, const int objqcol1[], const int obj
104103
std::function<int(XPRSprob prob, int nrows, const int rowind[], const double rhs[])> XPRSchgrhs = nullptr;
105104
std::function<int(XPRSprob prob, int nrows, const int rowind[], const double rng[])> XPRSchgrhsrange = nullptr;
106105
std::function<int(XPRSprob prob, int nrows, const int rowind[], const char rowtype[])> XPRSchgrowtype = nullptr;
106+
std::function<int(XPRSprob prob, int objidx)> XPRSdelobj = nullptr;
107107
std::function<int(XPRSprob prob, void (XPRS_CC *f_intsol)(XPRSprob cbprob, void* cbdata), void* p, int priority)> XPRSaddcbintsol = nullptr;
108108
std::function<int(XPRSprob prob, void (XPRS_CC *f_intsol)(XPRSprob cbprob, void* cbdata), void* p)> XPRSremovecbintsol = nullptr;
109109
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 = nullptr;
@@ -141,9 +141,8 @@ void LoadXpressFunctions(DynamicLibrary* xpress_dynamic_library) {
141141
xpress_dynamic_library->GetFunction(&XPRSgetdblcontrol, "XPRSgetdblcontrol");
142142
xpress_dynamic_library->GetFunction(&XPRSgetstringcontrol, "XPRSgetstringcontrol");
143143
xpress_dynamic_library->GetFunction(&XPRSgetintattrib, "XPRSgetintattrib");
144+
xpress_dynamic_library->GetFunction(&XPRSgetstringattrib, "XPRSgetstringattrib");
144145
xpress_dynamic_library->GetFunction(&XPRSgetdblattrib, "XPRSgetdblattrib");
145-
xpress_dynamic_library->GetFunction(&XPRSloadlp, "XPRSloadlp");
146-
xpress_dynamic_library->GetFunction(&XPRSloadlp64, "XPRSloadlp64");
147146
xpress_dynamic_library->GetFunction(&XPRSgetobj, "XPRSgetobj");
148147
xpress_dynamic_library->GetFunction(&XPRSgetrhs, "XPRSgetrhs");
149148
xpress_dynamic_library->GetFunction(&XPRSgetrhsrange, "XPRSgetrhsrange");
@@ -179,6 +178,7 @@ void LoadXpressFunctions(DynamicLibrary* xpress_dynamic_library) {
179178
xpress_dynamic_library->GetFunction(&XPRSchgrhs, "XPRSchgrhs");
180179
xpress_dynamic_library->GetFunction(&XPRSchgrhsrange, "XPRSchgrhsrange");
181180
xpress_dynamic_library->GetFunction(&XPRSchgrowtype, "XPRSchgrowtype");
181+
xpress_dynamic_library->GetFunction(&XPRSdelobj, "XPRSdelobj");
182182
xpress_dynamic_library->GetFunction(&XPRSaddcbintsol, "XPRSaddcbintsol");
183183
xpress_dynamic_library->GetFunction(&XPRSremovecbintsol, "XPRSremovecbintsol");
184184
xpress_dynamic_library->GetFunction(&XPRSaddcbmessage, "XPRSaddcbmessage");

ortools/xpress/environment.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,7 @@ absl::Status LoadXpressDynamicLibrary(std::string& xpresspath);
453453
#define XPRS_ALG_BARRIER 4
454454
#define XPRS_OBJ_MINIMIZE 1
455455
#define XPRS_OBJ_MAXIMIZE -1
456+
#define XPRS_UUID 3011
456457
// ***************************************************************************
457458
// * variable types *
458459
// ***************************************************************************
@@ -497,10 +498,9 @@ OR_DLL extern std::function<int(XPRSprob prob, int control, XPRSint64* p_value)>
497498
OR_DLL extern std::function<int(XPRSprob prob, int control, double* p_value)> XPRSgetdblcontrol;
498499
OR_DLL extern std::function<int(XPRSprob prob, int control, char* value, int maxbytes, int* p_nbytes)> XPRSgetstringcontrol;
499500
OR_DLL extern std::function<int(XPRSprob prob, int attrib, int* p_value)> XPRSgetintattrib;
501+
OR_DLL extern std::function<int(XPRSprob prob, int attrib, char* value, int maxbytes, int* p_nbytes)> XPRSgetstringattrib;
500502
OR_DLL extern std::function<int(XPRSprob prob, int attrib, double* p_value)> XPRSgetdblattrib;
501503
extern std::function<int(XPRSprob prob, const char* name, int* p_id, int* p_type)> XPRSgetcontrolinfo;
502-
extern std::function<int(XPRSprob prob, const char* probname, int ncols, int nrows, const char rowtype[], const double rhs[], const double rng[], const double objcoef[], const int start[], const int collen[], const int rowind[], const double rowcoef[], const double lb[], const double ub[])> XPRSloadlp;
503-
extern std::function<int(XPRSprob prob, const char* probname, int ncols, int nrows, const char rowtype[], const double rhs[], const double rng[], const double objcoef[], const XPRSint64 start[], const int collen[], const int rowind[], const double rowcoef[], const double lb[], const double ub[])> XPRSloadlp64;
504504
OR_DLL extern std::function<int(XPRSprob prob, double objcoef[], int first, int last)> XPRSgetobj;
505505
OR_DLL extern std::function<int(XPRSprob prob, double rhs[], int first, int last)> XPRSgetrhs;
506506
OR_DLL extern std::function<int(XPRSprob prob, double rng[], int first, int last)> XPRSgetrhsrange;
@@ -536,6 +536,7 @@ extern std::function<int(XPRSprob prob, int ncoefs, const int objqcol1[], const
536536
extern std::function<int(XPRSprob prob, int nrows, const int rowind[], const double rhs[])> XPRSchgrhs;
537537
extern std::function<int(XPRSprob prob, int nrows, const int rowind[], const double rng[])> XPRSchgrhsrange;
538538
extern std::function<int(XPRSprob prob, int nrows, const int rowind[], const char rowtype[])> XPRSchgrowtype;
539+
extern std::function<int(XPRSprob prob, int objidx)> XPRSdelobj;
539540
extern std::function<int(XPRSprob prob, void (XPRS_CC *f_intsol)(XPRSprob cbprob, void* cbdata), void* p, int priority)> XPRSaddcbintsol;
540541
extern std::function<int(XPRSprob prob, void (XPRS_CC *f_intsol)(XPRSprob cbprob, void* cbdata), void* p)> XPRSremovecbintsol;
541542
extern 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;

0 commit comments

Comments
 (0)