Skip to content

Commit

Permalink
Merge pull request #2005 from HaoZeke/tk3_scipy
Browse files Browse the repository at this point in the history
ENH: Update `highspy` bindings and cleanup `meson.build` for SciPy
  • Loading branch information
galabovaa authored Oct 29, 2024
2 parents a755161 + acf190d commit a8b5cc6
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 227 deletions.
15 changes: 8 additions & 7 deletions check/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,11 @@ foreach test : test_array
)
endforeach

if get_option('with_c')
test('test_capi',
executable('capi_unit_tests', 'TestCAPI.c',
include_directories: _incdirs,
link_with : highslib,
))
endif

test('test_capi',
executable('capi_unit_tests',
sources: ['TestCAPI.c', highs_conf_file],
include_directories: _incdirs,
link_with : highslib,
)
)
6 changes: 3 additions & 3 deletions meson_options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ option('with_fortran',
option('with_csharp',
type : 'boolean',
value : false)
option('with_c',
type : 'boolean',
value : false)
option('debug_sol',
type: 'boolean',
value: false)
Expand All @@ -29,3 +26,6 @@ option('with_tests',
option('with_pybind11',
type : 'boolean',
value : false)
option('do_install',
type : 'boolean',
value : true)
62 changes: 41 additions & 21 deletions src/highs_bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include "Highs.h"
#include "lp_data/HighsCallback.h"
#include "simplex/SimplexConst.h"

namespace py = pybind11;
using namespace pybind11::literals;
Expand Down Expand Up @@ -442,7 +443,6 @@ std::tuple<HighsStatus, double, double, double, HighsInt> highs_getCol(

std::tuple<HighsStatus, dense_array_t<HighsInt>, dense_array_t<double>>
highs_getColEntries(Highs* h, HighsInt col) {
double cost, lower, upper;
HighsInt get_num_col;
HighsInt get_num_nz;
HighsInt col_ = static_cast<HighsInt>(col);
Expand All @@ -462,7 +462,7 @@ highs_getColEntries(Highs* h, HighsInt col) {

std::tuple<HighsStatus, double, double, HighsInt> highs_getRow(Highs* h,
HighsInt row) {
double cost, lower, upper;
double lower, upper;
HighsInt get_num_row;
HighsInt get_num_nz;
HighsInt row_ = static_cast<HighsInt>(row);
Expand All @@ -473,7 +473,6 @@ std::tuple<HighsStatus, double, double, HighsInt> highs_getRow(Highs* h,

std::tuple<HighsStatus, dense_array_t<HighsInt>, dense_array_t<double>>
highs_getRowEntries(Highs* h, HighsInt row) {
double cost, lower, upper;
HighsInt get_num_row;
HighsInt get_num_nz;
HighsInt row_ = static_cast<HighsInt>(row);
Expand Down Expand Up @@ -624,7 +623,7 @@ HighsStatus highs_setCallback(
return h->setCallback((HighsCallbackFunctionType) nullptr, nullptr);
else
return h->setCallback(
[fn, data](int callbackType, const std::string& msg,
[fn](int callbackType, const std::string& msg,
const HighsCallbackDataOut* dataOut,
HighsCallbackDataIn* dataIn, void* d) {
return fn(callbackType, msg, dataOut, dataIn, py::handle(reinterpret_cast<PyObject*>(d)));
Expand All @@ -633,20 +632,25 @@ HighsStatus highs_setCallback(
}

PYBIND11_MODULE(_core, m) {
// enum classes
// To keep a smaller diff, for reviewers, the declarations are not moved, but
// keep in mind:
// C++ enum classes :: don't need .export_values()
// C++ enums, need .export_values()
// Quoting [1]:
// "The enum_::export_values() function exports the enum entries into the
// parent scope, which should be skipped for newer C++11-style strongly typed
// enums."
// [1]: https://pybind11.readthedocs.io/en/stable/classes.html
py::enum_<ObjSense>(m, "ObjSense")
.value("kMinimize", ObjSense::kMinimize)
.value("kMaximize", ObjSense::kMaximize);
// // .export_values();
py::enum_<MatrixFormat>(m, "MatrixFormat")
.value("kColwise", MatrixFormat::kColwise)
.value("kRowwise", MatrixFormat::kRowwise)
.value("kRowwisePartitioned", MatrixFormat::kRowwisePartitioned);
// // .export_values();
py::enum_<HessianFormat>(m, "HessianFormat")
.value("kTriangular", HessianFormat::kTriangular)
.value("kSquare", HessianFormat::kSquare);
// .export_values();
py::enum_<SolutionStatus>(m, "SolutionStatus")
.value("kSolutionStatusNone", SolutionStatus::kSolutionStatusNone)
.value("kSolutionStatusInfeasible",
Expand Down Expand Up @@ -677,7 +681,6 @@ PYBIND11_MODULE(_core, m) {
.value("kSolutionLimit", HighsModelStatus::kSolutionLimit)
.value("kInterrupt", HighsModelStatus::kInterrupt)
.value("kMemoryLimit", HighsModelStatus::kMemoryLimit);
// .export_values();
py::enum_<HighsPresolveStatus>(m, "HighsPresolveStatus")
.value("kNotPresolved", HighsPresolveStatus::kNotPresolved)
.value("kNotReduced", HighsPresolveStatus::kNotReduced)
Expand All @@ -689,59 +692,60 @@ PYBIND11_MODULE(_core, m) {
.value("kTimeout", HighsPresolveStatus::kTimeout)
.value("kNullError", HighsPresolveStatus::kNullError)
.value("kOptionsError", HighsPresolveStatus::kOptionsError);
// .export_values();
py::enum_<HighsBasisStatus>(m, "HighsBasisStatus")
.value("kLower", HighsBasisStatus::kLower)
.value("kBasic", HighsBasisStatus::kBasic)
.value("kUpper", HighsBasisStatus::kUpper)
.value("kZero", HighsBasisStatus::kZero)
.value("kNonbasic", HighsBasisStatus::kNonbasic);
// .export_values();
py::enum_<HighsVarType>(m, "HighsVarType")
.value("kContinuous", HighsVarType::kContinuous)
.value("kInteger", HighsVarType::kInteger)
.value("kSemiContinuous", HighsVarType::kSemiContinuous)
.value("kSemiInteger", HighsVarType::kSemiInteger);
// .export_values();
py::enum_<HighsOptionType>(m, "HighsOptionType")
.value("kBool", HighsOptionType::kBool)
.value("kInt", HighsOptionType::kInt)
.value("kDouble", HighsOptionType::kDouble)
.value("kString", HighsOptionType::kString);
// .export_values();
py::enum_<HighsInfoType>(m, "HighsInfoType")
.value("kInt64", HighsInfoType::kInt64)
.value("kInt", HighsInfoType::kInt)
.value("kDouble", HighsInfoType::kDouble);
// .export_values();
py::enum_<HighsStatus>(m, "HighsStatus")
.value("kError", HighsStatus::kError)
.value("kOk", HighsStatus::kOk)
.value("kWarning", HighsStatus::kWarning);
// .export_values();
py::enum_<HighsLogType>(m, "HighsLogType")
.value("kInfo", HighsLogType::kInfo)
.value("kDetailed", HighsLogType::kDetailed)
.value("kVerbose", HighsLogType::kVerbose)
.value("kWarning", HighsLogType::kWarning)
.value("kError", HighsLogType::kError);
// .export_values();
py::enum_<IisStrategy>(m, "IisStrategy")
.value("kIisStrategyMin", IisStrategy::kIisStrategyMin)
.value("kIisStrategyFromLpRowPriority",
IisStrategy::kIisStrategyFromLpRowPriority)
.value("kIisStrategyFromLpColPriority",
IisStrategy::kIisStrategyFromLpColPriority)
.value("kIisStrategyMax", IisStrategy::kIisStrategyMax);
// .export_values();
.value("kIisStrategyMax", IisStrategy::kIisStrategyMax)
.export_values();
py::enum_<IisBoundStatus>(m, "IisBoundStatus")
.value("kIisBoundStatusDropped", IisBoundStatus::kIisBoundStatusDropped)
.value("kIisBoundStatusNull", IisBoundStatus::kIisBoundStatusNull)
.value("kIisBoundStatusFree", IisBoundStatus::kIisBoundStatusFree)
.value("kIisBoundStatusLower", IisBoundStatus::kIisBoundStatusLower)
.value("kIisBoundStatusUpper", IisBoundStatus::kIisBoundStatusUpper)
.value("kIisBoundStatusBoxed", IisBoundStatus::kIisBoundStatusBoxed);
// .export_values();
.value("kIisBoundStatusBoxed", IisBoundStatus::kIisBoundStatusBoxed)
.export_values();
py::enum_<HighsDebugLevel>(m, "HighsDebugLevel")
.value("kHighsDebugLevelNone", HighsDebugLevel::kHighsDebugLevelNone)
.value("kHighsDebugLevelCheap", HighsDebugLevel::kHighsDebugLevelCheap)
.value("kHighsDebugLevelCostly", HighsDebugLevel::kHighsDebugLevelCostly)
.value("kHighsDebugLevelExpensive", HighsDebugLevel::kHighsDebugLevelExpensive)
.value("kHighsDebugLevelMin", HighsDebugLevel::kHighsDebugLevelMin)
.value("kHighsDebugLevelMax", HighsDebugLevel::kHighsDebugLevelMax)
.export_values();
// Classes
py::class_<HighsSparseMatrix>(m, "HighsSparseMatrix")
.def(py::init<>())
Expand Down Expand Up @@ -1158,7 +1162,23 @@ PYBIND11_MODULE(_core, m) {
.value("kSimplexStrategyPrimal", SimplexStrategy::kSimplexStrategyPrimal)
.value("kSimplexStrategyMax", SimplexStrategy::kSimplexStrategyMax)
.value("kSimplexStrategyNum", SimplexStrategy::kSimplexStrategyNum)
.export_values(); // needed since it isn't an enum class
.export_values();
py::enum_<SimplexCrashStrategy>(simplex_constants, "SimplexCrashStrategy")
.value("kSimplexCrashStrategyMin", SimplexCrashStrategy::kSimplexCrashStrategyMin)
.value("kSimplexCrashStrategyOff", SimplexCrashStrategy::kSimplexCrashStrategyOff)
.value("kSimplexCrashStrategyLtssfK", SimplexCrashStrategy::kSimplexCrashStrategyLtssfK)
.value("kSimplexCrashStrategyLtssf", SimplexCrashStrategy::kSimplexCrashStrategyLtssf)
.value("kSimplexCrashStrategyBixby", SimplexCrashStrategy::kSimplexCrashStrategyBixby)
.value("kSimplexCrashStrategyLtssfPri", SimplexCrashStrategy::kSimplexCrashStrategyLtssfPri)
.value("kSimplexCrashStrategyLtsfK", SimplexCrashStrategy::kSimplexCrashStrategyLtsfK)
.value("kSimplexCrashStrategyLtsfPri", SimplexCrashStrategy::kSimplexCrashStrategyLtsfPri)
.value("kSimplexCrashStrategyLtsf", SimplexCrashStrategy::kSimplexCrashStrategyLtsf)
.value("kSimplexCrashStrategyBixbyNoNonzeroColCosts",
SimplexCrashStrategy::kSimplexCrashStrategyBixbyNoNonzeroColCosts)
.value("kSimplexCrashStrategyBasic", SimplexCrashStrategy::kSimplexCrashStrategyBasic)
.value("kSimplexCrashStrategyTestSing", SimplexCrashStrategy::kSimplexCrashStrategyTestSing)
.value("kSimplexCrashStrategyMax", SimplexCrashStrategy::kSimplexCrashStrategyMax)
.export_values();
py::enum_<SimplexUnscaledSolutionStrategy>(simplex_constants,
"SimplexUnscaledSolutionStrategy")
.value(
Expand Down
94 changes: 0 additions & 94 deletions src/highs_options.cpp

This file was deleted.

Loading

0 comments on commit a8b5cc6

Please sign in to comment.