Skip to content

Commit

Permalink
try using patch.py
Browse files Browse the repository at this point in the history
  • Loading branch information
sgatto committed Sep 23, 2024
1 parent 2626e6a commit 6a32fe2
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 117 deletions.
1 change: 0 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ FetchContent_Declare(ortools
${CMAKE_CURRENT_SOURCE_DIR}/ortools
${CMAKE_CURRENT_SOURCE_DIR}/cmake_patches
. && ${Python3_EXECUTABLE} patch.py
&& git apply ${CMAKE_CURRENT_SOURCE_DIR}/fix_locale_bug.patch
OVERRIDE_FIND_PACKAGE ON
)
message("BUILD_DEPS: " ${BUILD_DEPS})
Expand Down
96 changes: 0 additions & 96 deletions fix_locale_bug.patch

This file was deleted.

141 changes: 122 additions & 19 deletions patch.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
from typing import List
from patch_utils import *

full_patch: List[Addition] = []
additions: List[Addition] = []
replacements: List[Replacement] = []

# add the USE_SIRIUS configuration flag in CMakeLists.txt
full_patch.append(Addition(
additions.append(Addition(
Path.cwd()/'CMakeLists.txt',
'''option(USE_CPLEX "Use the CPLEX solver" OFF)
message(STATUS "CPLEX support: ${USE_CPLEX}")
Expand All @@ -18,12 +19,12 @@

# add the USE_SIRIUS configuration flag in cpp.cmake

full_patch.append(
additions.append(
Addition(
Path.cwd()/'cmake'/'cpp.cmake',
' $<$<BOOL:${USE_SCIP}>:libscip>\n',
' $<$<BOOL:${USE_SIRIUS}>:sirius_solver>\n'))
full_patch.append(Addition(
additions.append(Addition(
Path.cwd()/'cmake'/'cpp.cmake',
'''
if(USE_CPLEX)
Expand All @@ -37,7 +38,7 @@
'''))

# add the USE_SIRIUS configuration flag in deps.cmake
full_patch.append(Addition(
additions.append(Addition(
Path.cwd()/'cmake'/'system_deps.cmake',
'''
if(USE_CPLEX)
Expand All @@ -56,7 +57,7 @@
'''))

# add the USE_SIRIUS configuration flag in ortoolsConfig.cmake.in
full_patch.append(Addition(
additions.append(Addition(
Path.cwd()/'cmake'/'ortoolsConfig.cmake.in',
'''
if(@USE_SCIP@)
Expand All @@ -77,38 +78,38 @@
'''))

# add SIRIUS execution in example files
full_patch.append(Addition(
additions.append(Addition(
Path.cwd()/'examples'/'cpp'/'linear_programming.cc',
' RunLinearProgrammingExample("XPRESS_LP");\n',
' RunLinearProgrammingExample("SIRIUS_LP");\n'
))

full_patch.append(Addition(
additions.append(Addition(
Path.cwd()/'examples'/'dotnet'/'cslinearprogramming.cs',
' RunLinearProgrammingExample("XPRESS_LP");\n',
' RunLinearProgrammingExample("SIRIUS_LP");\n'
))

full_patch.append(Addition(
additions.append(Addition(
Path.cwd()/'examples'/'java'/'LinearProgramming.java',
''' runLinearProgrammingExample("CLP", false);
''',
''' System.out.println("---- Linear programming example with Sirius ----");
runLinearProgrammingExample("SIRIUS_LP", false);
'''))

full_patch.append(Addition(
additions.append(Addition(
Path.cwd()/'examples'/'python'/'linear_programming.py',
' RunLinearExampleCppStyleAPI("XPRESS_LP")\n',
' RunLinearExampleCppStyleAPI("SIRIUS_LP")\n'))

# add the USE_SIRIUS configuration flag in ortools/linear_solver/CMakeLists.txt
full_patch.append(Addition(
additions.append(Addition(
Path.cwd()/'ortools'/'linear_solver'/'CMakeLists.txt',
' $<$<BOOL:${USE_SCIP}>:libscip>\n',
' $<$<BOOL:${USE_SIRIUS}>:sirius_solver>\n'))

full_patch.append(Addition(
additions.append(Addition(
Path.cwd()/'ortools'/'linear_solver'/'CMakeLists.txt',
''' add_test(NAME cxx_unittests_xpress_interface COMMAND test_xprs_interface)
''',
Expand All @@ -122,7 +123,7 @@
'''))

# add the SIRIUS support in ortools/linear_solver/linear_solver.cc & .h
full_patch.append(Addition(
additions.append(Addition(
Path.cwd()/'ortools'/'linear_solver'/'linear_solver.cc',
'''extern MPSolverInterface* BuildXpressInterface(bool mip,
MPSolver* const solver);
Expand All @@ -132,7 +133,7 @@
#endif
'''))

full_patch.append(Addition(
additions.append(Addition(
Path.cwd()/'ortools'/'linear_solver'/'linear_solver.cc',
''' return BuildXpressInterface(false, solver);
''',
Expand All @@ -144,7 +145,7 @@
#endif
'''))

full_patch.append(Addition(
additions.append(Addition(
Path.cwd()/'ortools'/'linear_solver'/'linear_solver.cc',
'''#ifdef USE_CPLEX
if (problem_type == CPLEX_LINEAR_PROGRAMMING ||
Expand All @@ -159,27 +160,129 @@
#endif
'''))

full_patch.append(Addition(
additions.append(Addition(
Path.cwd()/'ortools'/'linear_solver'/'linear_solver.cc',
''' {MPSolver::XPRESS_MIXED_INTEGER_PROGRAMMING, "xpress"},
''',
''' {MPSolver::SIRIUS_LINEAR_PROGRAMMING, "sirius_lp"},
{MPSolver::SIRIUS_MIXED_INTEGER_PROGRAMMING, "sirius"},
'''))

full_patch.append(Addition(
additions.append(Addition(
Path.cwd()/'ortools'/'linear_solver'/'linear_solver.h',
''' COPT_MIXED_INTEGER_PROGRAMMING = 104,
''',
''' SIRIUS_LINEAR_PROGRAMMING = 105,
SIRIUS_MIXED_INTEGER_PROGRAMMING = 106,
'''))

full_patch.append(Addition(
additions.append(Addition(
Path.cwd()/'ortools'/'linear_solver'/'linear_solver.h',
' friend class XpressInterface;\n',
' friend class SiriusInterface;\n'))

# add temporary patch for XPressInterface
additions.append(Addition(
Path.cwd()/'ortools'/'linear_solver'/'xpress_interface.cc',
'''#include "absl/strings/str_format.h"
#include "ortools/base/logging.h"''',
'''#include "absl/strings/numbers.h"
#include "absl/strings/str_format.h"
#include "ortools/base/logging.h"'''))

replacements.append(Replacement(
Path.cwd()/'ortools'/'linear_solver'/'xpress_interface.cc',
''' }
}
const char* stringToCharPtr(std::string& var) { return var.c_str(); }
// Save the existing locale, use the "C" locale to ensure that
// string -> double conversion is done ignoring the locale.
struct ScopedLocale {
ScopedLocale() {
oldLocale = std::setlocale(LC_NUMERIC, nullptr);
auto newLocale = std::setlocale(LC_NUMERIC, "C");
CHECK_EQ(std::string(newLocale), "C");
}
~ScopedLocale() { std::setlocale(LC_NUMERIC, oldLocale); }
+bool stringToCharPtr(const std::string& var, const char** out) {
private:
const char* oldLocale;
};
#define setParamIfPossible_MACRO(target_map, setter, converter) \
{ \
auto matchingParamIter = (target_map).find(paramAndValuePair.first); \
if (matchingParamIter != (target_map).end()) { \
const auto convertedValue = converter(paramAndValuePair.second); \
VLOG(1) << "Setting parameter " << paramAndValuePair.first \
<< " to value " << convertedValue << std::endl; \
setter(mLp, matchingParamIter->second, convertedValue); \
continue; \
}''',
''' }
}
bool stringToCharPtr(const std::string& var, const char** out) {
*out = var.c_str();
return true;
}
#define setParamIfPossible_MACRO(target_map, setter, converter, type) \
{ \
auto matchingParamIter = (target_map).find(paramAndValuePair.first); \
if (matchingParamIter != (target_map).end()) { \
type convertedValue; \
bool ret = converter(paramAndValuePair.second, &convertedValue); \
if (ret) { \
VLOG(1) << "Setting parameter " << paramAndValuePair.first \
<< " to value " << convertedValue << std::endl; \
} \
setter(mLp, matchingParamIter->second, convertedValue); \
continue; \
}'''
))

replacements.append(Replacement(
Path.cwd()/'ortools'/'linear_solver'/'xpress_interface.cc',
''' }
}
ScopedLocale locale;
for (auto& paramAndValuePair : paramAndValuePairList) {
setParamIfPossible_MACRO(mapIntegerControls_, XPRSsetintcontrol, std::stoi);
setParamIfPossible_MACRO(mapDoubleControls_, XPRSsetdblcontrol, std::stod);
setParamIfPossible_MACRO(mapStringControls_, XPRSsetstrcontrol,
stringToCharPtr);
setParamIfPossible_MACRO(mapInteger64Controls_, XPRSsetintcontrol64,
std::stoll);
LOG(ERROR) << "Unknown parameter " << paramName << " : function "
<< __FUNCTION__ << std::endl;
return false;
''',
''' }
}
for (auto& paramAndValuePair : paramAndValuePairList) {
setParamIfPossible_MACRO(mapIntegerControls_, XPRSsetintcontrol,
absl::SimpleAtoi<int>, int);
setParamIfPossible_MACRO(mapDoubleControls_, XPRSsetdblcontrol,
absl::SimpleAtod, double);
setParamIfPossible_MACRO(mapStringControls_, XPRSsetstrcontrol,
stringToCharPtr, const char*);
setParamIfPossible_MACRO(mapInteger64Controls_, XPRSsetintcontrol64,
absl::SimpleAtoi<int64_t>, int64_t);
LOG(ERROR) << "Unknown parameter " << paramName << " : function "
<< __FUNCTION__ << std::endl;
return false;
'''
))


# run patch
for a in full_patch:
for a in additions:
replace_in_file(a.filepath, a.search, a.search+a.add)
for r in replacements:
replace_in_file(r.filepath, r.search, r.replace)
8 changes: 7 additions & 1 deletion patch_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,10 @@ def replace_in_file(filepath, search, replace):
class Addition:
filepath: Path
search: str
add: str
add: str

@dataclass
class Replacement:
filepath: Path
search: str
replace: str

0 comments on commit 6a32fe2

Please sign in to comment.