From 6339eb6931766da8e4c50a481a49e6573be990bb Mon Sep 17 00:00:00 2001 From: James Tomlinson Date: Sun, 23 Jun 2024 20:39:22 +0100 Subject: [PATCH] feat: Add additional COIN-OR bindings for Cbc. This requires adding Cgl and Osi libraries. Currently these are vendored in the same way as Clp. --- .gitmodules | 13 +- Cargo.toml | 6 +- clp-sys/build.rs | 195 ------ clp-sys/src/lib.rs | 28 - {clp-sys => coin-or-sys}/Cargo.toml | 4 +- coin-or-sys/build.rs | 476 +++++++++++++ coin-or-sys/src/cbc.rs | 634 ++++++++++++++++++ .../src/bindings.rs => coin-or-sys/src/clp.rs | 0 coin-or-sys/src/lib.rs | 53 ++ coin-or-sys/vendor/Cbc | 1 + coin-or-sys/vendor/Cgl | 1 + {clp-sys => coin-or-sys}/vendor/Clp | 0 {clp-sys => coin-or-sys}/vendor/CoinUtils | 0 coin-or-sys/vendor/Osi | 1 + pywr-core/Cargo.toml | 4 +- pywr-core/src/solvers/clp/mod.rs | 2 +- 16 files changed, 1185 insertions(+), 233 deletions(-) delete mode 100644 clp-sys/build.rs delete mode 100644 clp-sys/src/lib.rs rename {clp-sys => coin-or-sys}/Cargo.toml (85%) create mode 100644 coin-or-sys/build.rs create mode 100644 coin-or-sys/src/cbc.rs rename clp-sys/src/bindings.rs => coin-or-sys/src/clp.rs (100%) create mode 100644 coin-or-sys/src/lib.rs create mode 160000 coin-or-sys/vendor/Cbc create mode 160000 coin-or-sys/vendor/Cgl rename {clp-sys => coin-or-sys}/vendor/Clp (100%) rename {clp-sys => coin-or-sys}/vendor/CoinUtils (100%) create mode 160000 coin-or-sys/vendor/Osi diff --git a/.gitmodules b/.gitmodules index e18a59d3..d674f2f0 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,15 @@ [submodule "clp-sys/vendor/Clp"] - path = clp-sys/vendor/Clp + path = coin-or-sys/vendor/Clp url = https://github.com/coin-or/Clp [submodule "clp-sys/vendor/CoinUtils"] - path = clp-sys/vendor/CoinUtils + path = coin-or-sys/vendor/CoinUtils url = https://github.com/coin-or/CoinUtils.git +[submodule "coin-or-sys/vendor/Cgl"] + path = coin-or-sys/vendor/Cgl + url = https://github.com/coin-or/Cgl.git +[submodule "coin-or-sys/vendor/Cbc"] + path = coin-or-sys/vendor/Cbc + url = https://github.com/coin-or/Cbc.git +[submodule "coin-or-sys/vendor/Osi"] + path = coin-or-sys/vendor/Osi + url = https://github.com/coin-or/Osi diff --git a/Cargo.toml b/Cargo.toml index 7f69e387..f43cd68c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ members = [ "ipm-common", "ipm-ocl", "ipm-simd", - "clp-sys", + "coin-or-sys", "pywr-core", "pywr-schema", "pywr-cli", @@ -16,7 +16,7 @@ exclude = [ ] # IPM packages are not default because they require nightly (portable_simd). default-members = [ - "clp-sys", + "coin-or-sys", "pywr-core", "pywr-schema", "pywr-cli", @@ -47,5 +47,5 @@ tracing = { version = "0.1", features = ["log"] } csv = "1.1" hdf5 = { git = "https://github.com/aldanor/hdf5-rust.git", package = "hdf5", features = ["static", "zlib"] } pywr-v1-schema = { git = "https://github.com/pywr/pywr-schema/", tag = "v0.13.0", package = "pywr-schema" } -chrono = { version = "0.4.34" } +chrono = { version = "0.4.34", features = ["serde"] } schemars = { version = "0.8.16", features = ["chrono"] } diff --git a/clp-sys/build.rs b/clp-sys/build.rs deleted file mode 100644 index 1e2c5336..00000000 --- a/clp-sys/build.rs +++ /dev/null @@ -1,195 +0,0 @@ -use std::env; - -fn make_builder() -> cc::Build { - let target = env::var("TARGET").expect("Could not find TARGET in environment."); - let mut builder = cc::Build::new() - .cpp(true) - .warnings(false) - .extra_warnings(false) - .define("NDEBUG", None) - .define("HAVE_STDIO_H", None) - .define("HAVE_STDLIB_H", None) - .define("HAVE_STRING_H", None) - .define("HAVE_INTTYPES_H", None) - .define("HAVE_STDINT_H", None) - .define("HAVE_STRINGS_H", None) - .define("HAVE_SYS_TYPES_H", None) - .define("HAVE_SYS_STAT_H", None) - .define("HAVE_UNISTD_H", None) - .define("HAVE_CMATH", None) - .define("HAVE_CFLOAT", None) - // .define("HAVE_DLFCN_H", None) - .define("HAVE_MEMORY_H", None) - .to_owned(); - - if target.contains("msvc") { - builder.flag("-EHsc"); - // Flag required for macros __cplusplus to work correctly. - // See: https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/ - builder.flag("/Zc:__cplusplus"); - builder.flag("/std:c++14"); - } else { - builder.flag("-std=c++11"); - builder.flag("-w"); - } - - builder -} - -fn main() { - const COIN_UTILS_SRC: &str = "vendor/CoinUtils/CoinUtils/src"; - const COIN_CLP_SRC: &str = "vendor/Clp/Clp/src"; - - // Compile CoinUtils - let mut builder = make_builder(); - - builder - .flag(&format!("-I{}", COIN_UTILS_SRC)) - .file(format!("{}/CoinAlloc.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinBuild.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinDenseFactorization.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinDenseVector.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinError.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinFactorization1.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinFactorization2.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinFactorization3.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinFactorization4.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinFileIO.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinFinite.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinIndexedVector.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinLpIO.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinMessage.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinMessageHandler.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinModel.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinModelUseful2.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinModelUseful.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinMpsIO.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinOslFactorization2.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinOslFactorization3.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinOslFactorization.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinPackedMatrix.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinPackedVectorBase.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinPackedVector.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinParam.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinParamUtils.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinPostsolveMatrix.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinPrePostsolveMatrix.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinPresolveDoubleton.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinPresolveDual.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinPresolveDupcol.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinPresolveEmpty.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinPresolveFixed.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinPresolveForcing.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinPresolveHelperFunctions.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinPresolveImpliedFree.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinPresolveIsolated.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinPresolveMatrix.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinPresolveMonitor.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinPresolvePsdebug.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinPresolveSingleton.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinPresolveSubst.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinPresolveTighten.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinPresolveTripleton.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinPresolveUseless.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinPresolveZeros.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinRational.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinSearchTree.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinShallowPackedVector.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinSimpFactorization.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinSnapshot.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinStructuredModel.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinWarmStartBasis.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinWarmStartDual.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinWarmStartPrimalDual.cpp", COIN_UTILS_SRC)) - .file(format!("{}/CoinWarmStartVector.cpp", COIN_UTILS_SRC)) - .compile("CoinUtils"); - - // Compile CoinUtils - - let mut builder = make_builder(); - - builder - .flag(&format!("-I{}", COIN_UTILS_SRC)) - .flag(&format!("-I{}", COIN_CLP_SRC)) - .file(format!("{}/ClpCholeskyBase.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpCholeskyDense.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpCholeskyPardiso.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpCholeskyTaucs.cpp", COIN_CLP_SRC)) - // Need to have AMD or CHOLMOD to compile ClpCholeskyUfl. - //.file(format!("{}/ClpCholeskyUfl.cpp", COIN_CLP_SRC)) - //.file(format!("{}/ClpCholeskyWssmp.cpp", COIN_CLP_SRC)) - //.file(format!("{}/ClpCholeskyWssmpKKT.cpp", COIN_CLP_SRC)) - .file(format!("{}/Clp_C_Interface.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpConstraint.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpConstraintLinear.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpConstraintQuadratic.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpDualRowDantzig.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpDualRowPivot.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpDualRowSteepest.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpDummyMatrix.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpDynamicExampleMatrix.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpDynamicMatrix.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpEventHandler.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpFactorization.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpGubDynamicMatrix.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpGubMatrix.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpHelperFunctions.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpInterior.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpLinearObjective.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpLsqr.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpMatrixBase.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpMessage.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpModel.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpNetworkBasis.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpNetworkMatrix.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpNode.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpObjective.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpNonLinearCost.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpPackedMatrix.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpPdcoBase.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpPdco.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpPEDualRowDantzig.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpPEDualRowSteepest.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpPEPrimalColumnDantzig.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpPEPrimalColumnSteepest.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpPESimplex.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpPlusMinusOneMatrix.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpPredictorCorrector.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpPresolve.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpPrimalColumnDantzig.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpPrimalColumnPivot.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpPrimalColumnSteepest.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpQuadraticObjective.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpSimplex.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpSimplexDual.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpSimplexNonlinear.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpSimplexOther.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpSimplexPrimal.cpp", COIN_CLP_SRC)) - .file(format!("{}/ClpSolve.cpp", COIN_CLP_SRC)) - // .file(format!("{}/ClpSolver.cpp", COIN_CLP_SRC)) - // .file(format!("{}/CoinAbcBaseFactorization1.cpp", COIN_CLP_SRC)) - // .file(format!("{}/CoinAbcBaseFactorization2.cpp", COIN_CLP_SRC)) - // .file(format!("{}/CoinAbcBaseFactorization3.cpp", COIN_CLP_SRC)) - // .file(format!("{}/CoinAbcBaseFactorization4.cpp", COIN_CLP_SRC)) - // .file(format!("{}/CoinAbcBaseFactorization5.cpp", COIN_CLP_SRC)) - // .file(format!("{}/CoinAbcDenseFactorization.cpp", COIN_CLP_SRC)) - // .file(format!("{}/CoinAbcFactorization1.cpp", COIN_CLP_SRC)) - // .file(format!("{}/CoinAbcFactorization2.cpp", COIN_CLP_SRC)) - // .file(format!("{}/CoinAbcFactorization3.cpp", COIN_CLP_SRC)) - // .file(format!("{}/CoinAbcFactorization4.cpp", COIN_CLP_SRC)) - // .file(format!("{}/CoinAbcFactorization5.cpp", COIN_CLP_SRC)) - // .file(format!("{}/CoinAbcHelperFunctions.cpp", COIN_CLP_SRC)) - // .file(format!("{}/CoinAbcOrderedFactorization1.cpp", COIN_CLP_SRC)) - // .file(format!("{}/CoinAbcOrderedFactorization2.cpp", COIN_CLP_SRC)) - // .file(format!("{}/CoinAbcOrderedFactorization3.cpp", COIN_CLP_SRC)) - // .file(format!("{}/CoinAbcOrderedFactorization4.cpp", COIN_CLP_SRC)) - // .file(format!("{}/CoinAbcOrderedFactorization5.cpp", COIN_CLP_SRC)) - // .file(format!("{}/CoinAbcSmallFactorization1.cpp", COIN_CLP_SRC)) - // .file(format!("{}/CoinAbcSmallFactorization2.cpp", COIN_CLP_SRC)) - // .file(format!("{}/CoinAbcSmallFactorization3.cpp", COIN_CLP_SRC)) - // .file(format!("{}/CoinAbcSmallFactorization4.cpp", COIN_CLP_SRC)) - // .file(format!("{}/CoinAbcSmallFactorization5.cpp", COIN_CLP_SRC)) - .file(format!("{}/Idiot.cpp", COIN_CLP_SRC)) - .file(format!("{}/IdiSolve.cpp", COIN_CLP_SRC)) - .compile("Clp"); -} diff --git a/clp-sys/src/lib.rs b/clp-sys/src/lib.rs deleted file mode 100644 index ef877157..00000000 --- a/clp-sys/src/lib.rs +++ /dev/null @@ -1,28 +0,0 @@ -#![allow(non_upper_case_globals)] -#![allow(non_camel_case_types)] -#![allow(non_snake_case)] - -include!("bindings.rs"); - -#[cfg(test)] -mod tests { - use super::{Clp_Version, Clp_deleteModel, Clp_newModel}; - - #[test] - fn test_clp_version() { - unsafe { - let c_buf = Clp_Version(); - let c_str = std::ffi::CStr::from_ptr(c_buf); - let version = c_str.to_str().unwrap(); - println!("{}", version); - } - } - - #[test] - fn test_model() { - unsafe { - let model = Clp_newModel(); - Clp_deleteModel(model); - } - } -} diff --git a/clp-sys/Cargo.toml b/coin-or-sys/Cargo.toml similarity index 85% rename from clp-sys/Cargo.toml rename to coin-or-sys/Cargo.toml index 2281569b..01082411 100644 --- a/clp-sys/Cargo.toml +++ b/coin-or-sys/Cargo.toml @@ -1,9 +1,9 @@ [package] -name = "clp-sys" +name = "coin-or-sys" version = "0.1.0" authors = ["James Tomlinson "] edition = "2021" -description = "Low-level bindings to COIN-OR CLP (Coin-or linear programming)." +description = "Low-level bindings to COIN-OR CLP (Coin-or linear programming) and CBC (Coin-or branch and cut)." license = "MIT OR Apache-2.0" repository = "https://github.com/pywr/pywr-next/" diff --git a/coin-or-sys/build.rs b/coin-or-sys/build.rs new file mode 100644 index 00000000..d3c93efc --- /dev/null +++ b/coin-or-sys/build.rs @@ -0,0 +1,476 @@ +use std::env; + +fn make_builder() -> cc::Build { + let target = env::var("TARGET").expect("Could not find TARGET in environment."); + let mut builder = cc::Build::new() + .cpp(true) + .warnings(false) + .extra_warnings(false) + .define("NDEBUG", None) + .define("HAVE_STDIO_H", None) + .define("HAVE_STDLIB_H", None) + .define("HAVE_STRING_H", None) + .define("HAVE_INTTYPES_H", None) + .define("HAVE_STDINT_H", None) + .define("HAVE_STRINGS_H", None) + .define("HAVE_SYS_TYPES_H", None) + .define("HAVE_SYS_STAT_H", None) + .define("HAVE_UNISTD_H", None) + .define("HAVE_CMATH", None) + .define("HAVE_CFLOAT", None) + // .define("HAVE_DLFCN_H", None) + .define("HAVE_MEMORY_H", None) + .to_owned(); + + if target.contains("msvc") { + builder.flag("-EHsc"); + // Flag required for macros __cplusplus to work correctly. + // See: https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/ + builder.flag("/Zc:__cplusplus"); + builder.flag("/std:c++14"); + } else { + builder.flag("-std=c++11"); + builder.flag("-w"); + } + + builder +} + +const COIN_UTILS_PATH: &str = "vendor/CoinUtils/CoinUtils/src"; + +const COIN_UTILS_SRCS: [&str; 57] = [ + "CoinAlloc.cpp", + "CoinBuild.cpp", + "CoinDenseFactorization.cpp", + "CoinDenseVector.cpp", + "CoinError.cpp", + "CoinFactorization1.cpp", + "CoinFactorization2.cpp", + "CoinFactorization3.cpp", + "CoinFactorization4.cpp", + "CoinFileIO.cpp", + "CoinFinite.cpp", + "CoinIndexedVector.cpp", + "CoinLpIO.cpp", + "CoinMessage.cpp", + "CoinMessageHandler.cpp", + "CoinModel.cpp", + "CoinModelUseful2.cpp", + "CoinModelUseful.cpp", + "CoinMpsIO.cpp", + "CoinOslFactorization2.cpp", + "CoinOslFactorization3.cpp", + "CoinOslFactorization.cpp", + "CoinPackedMatrix.cpp", + "CoinPackedVectorBase.cpp", + "CoinPackedVector.cpp", + "CoinParam.cpp", + "CoinParamUtils.cpp", + "CoinPostsolveMatrix.cpp", + "CoinPrePostsolveMatrix.cpp", + "CoinPresolveDoubleton.cpp", + "CoinPresolveDual.cpp", + "CoinPresolveDupcol.cpp", + "CoinPresolveEmpty.cpp", + "CoinPresolveFixed.cpp", + "CoinPresolveForcing.cpp", + "CoinPresolveHelperFunctions.cpp", + "CoinPresolveImpliedFree.cpp", + "CoinPresolveIsolated.cpp", + "CoinPresolveMatrix.cpp", + "CoinPresolveMonitor.cpp", + "CoinPresolvePsdebug.cpp", + "CoinPresolveSingleton.cpp", + "CoinPresolveSubst.cpp", + "CoinPresolveTighten.cpp", + "CoinPresolveTripleton.cpp", + "CoinPresolveUseless.cpp", + "CoinPresolveZeros.cpp", + "CoinRational.cpp", + "CoinSearchTree.cpp", + "CoinShallowPackedVector.cpp", + "CoinSimpFactorization.cpp", + "CoinSnapshot.cpp", + "CoinStructuredModel.cpp", + "CoinWarmStartBasis.cpp", + "CoinWarmStartDual.cpp", + "CoinWarmStartPrimalDual.cpp", + "CoinWarmStartVector.cpp", +]; + +/// Compile CoinUtils +fn compile_coin_utils() { + let mut builder = make_builder(); + + builder.flag(&format!("-I{}", COIN_UTILS_PATH)); + + for src in COIN_UTILS_SRCS.iter() { + builder.file(format!("{}/{}", COIN_UTILS_PATH, src)); + } + + builder.compile("CoinUtils"); +} + +const OSI_SRC_PATH: &str = "vendor/Osi/Osi/src/Osi"; +const OSI_SRCS: [&str; 12] = [ + "OsiAuxInfo.cpp", + "OsiBranchingObject.cpp", + "OsiChooseVariable.cpp", + "OsiColCut.cpp", + "OsiCut.cpp", + "OsiCuts.cpp", + "OsiNames.cpp", + "OsiPresolve.cpp", + "OsiRowCut.cpp", + "OsiRowCutDebugger.cpp", + "OsiSolverBranch.cpp", + "OsiSolverInterface.cpp", +]; + +/// Compiler Osi +/// +/// This does not include any of the interfaces, but is required for Cgl. +fn compile_osi() { + let mut builder = make_builder(); + + builder + .flag(&format!("-I{}", COIN_UTILS_PATH)) + .flag(&format!("-I{}", OSI_SRC_PATH)); + + for src in OSI_SRCS.iter() { + builder.file(format!("{}/{}", OSI_SRC_PATH, src)); + } + + builder.compile("Osi"); +} + +const CLP_SRC_PATH: &str = "vendor/Clp/Clp/src"; +const CLP_OSI_SRC_PATH: &str = "vendor/Clp/Clp/src/OsiClp"; + +const CLP_SRCS: [&str; 53] = [ + "ClpCholeskyBase.cpp", + "ClpCholeskyDense.cpp", + "ClpCholeskyPardiso.cpp", + "ClpCholeskyTaucs.cpp", + // Need to have AMD or CHOLMOD to compile ClpCholeskyUfl. + //"ClpCholeskyUfl.cpp", + //"ClpCholeskyWssmp.cpp", + //"ClpCholeskyWssmpKKT.cpp", + "Clp_C_Interface.cpp", + "ClpConstraint.cpp", + "ClpConstraintLinear.cpp", + "ClpConstraintQuadratic.cpp", + "ClpDualRowDantzig.cpp", + "ClpDualRowPivot.cpp", + "ClpDualRowSteepest.cpp", + "ClpDummyMatrix.cpp", + "ClpDynamicExampleMatrix.cpp", + "ClpDynamicMatrix.cpp", + "ClpEventHandler.cpp", + "ClpFactorization.cpp", + "ClpGubDynamicMatrix.cpp", + "ClpGubMatrix.cpp", + "ClpHelperFunctions.cpp", + "ClpInterior.cpp", + "ClpLinearObjective.cpp", + "ClpLsqr.cpp", + "ClpMatrixBase.cpp", + "ClpMessage.cpp", + "ClpModel.cpp", + "ClpNetworkBasis.cpp", + "ClpNetworkMatrix.cpp", + "ClpNode.cpp", + "ClpObjective.cpp", + "ClpNonLinearCost.cpp", + "ClpPackedMatrix.cpp", + "ClpPdcoBase.cpp", + "ClpPdco.cpp", + "ClpPEDualRowDantzig.cpp", + "ClpPEDualRowSteepest.cpp", + "ClpPEPrimalColumnDantzig.cpp", + "ClpPEPrimalColumnSteepest.cpp", + "ClpPESimplex.cpp", + "ClpPlusMinusOneMatrix.cpp", + "ClpPredictorCorrector.cpp", + "ClpPresolve.cpp", + "ClpPrimalColumnDantzig.cpp", + "ClpPrimalColumnPivot.cpp", + "ClpPrimalColumnSteepest.cpp", + "ClpQuadraticObjective.cpp", + "ClpSimplex.cpp", + "ClpSimplexDual.cpp", + "ClpSimplexNonlinear.cpp", + "ClpSimplexOther.cpp", + "ClpSimplexPrimal.cpp", + "ClpSolve.cpp", + "Idiot.cpp", + "IdiSolve.cpp", +]; + +fn compile_clp() { + let mut builder = make_builder(); + + builder + .include(COIN_UTILS_PATH) + .include(OSI_SRC_PATH) + .include(CLP_SRC_PATH); + + for src in CLP_SRCS.iter() { + builder.file(format!("{}/{}", CLP_SRC_PATH, src)); + } + + builder.file(format!("{}/OsiClpSolverInterface.cpp", CLP_OSI_SRC_PATH)); + builder.include(CLP_OSI_SRC_PATH); + + builder.compile("Clp"); +} + +const CGL_SRC_PATH: &str = "vendor/Cgl/Cgl/src"; +const CGL_SRCS: [&str; 5] = [ + "CglCutGenerator.cpp", + "CglMessage.cpp", + "CglParam.cpp", + "CglStored.cpp", + "CglTreeInfo.cpp", +]; + +fn compile_cgl() -> Vec { + let mut builder = make_builder(); + + let mut extra_include_dirs = vec![]; + + builder + .include(COIN_UTILS_PATH) + .include(OSI_SRC_PATH) + .include(CLP_SRC_PATH) + .include(CLP_OSI_SRC_PATH) + .include(CGL_SRC_PATH); + + for src in CGL_SRCS.iter() { + builder.file(format!("{}/{}", CGL_SRC_PATH, src)); + } + + { + let pth = format!("{}/CglAllDifferent", CGL_SRC_PATH); + builder.file(format!("{}/CglAllDifferent.cpp", pth)); + extra_include_dirs.push(pth); + } + + { + let pth = format!("{}/CglClique", CGL_SRC_PATH); + builder.file(format!("{}/CglClique.cpp", pth)); + extra_include_dirs.push(pth); + } + + { + let pth = format!("{}/CglDuplicateRow", CGL_SRC_PATH); + builder.file(format!("{}/CglDuplicateRow.cpp", pth)); + extra_include_dirs.push(pth); + } + + { + let pth = format!("{}/CglFlowCover", CGL_SRC_PATH); + builder.file(format!("{}/CglFlowCover.cpp", pth)); + extra_include_dirs.push(pth); + } + + { + let pth = format!("{}/CglGMI", CGL_SRC_PATH); + builder.file(format!("{}/CglGMI.cpp", pth)); + builder.file(format!("{}/CglGMIParam.cpp", pth)); + extra_include_dirs.push(pth); + } + + { + let pth = format!("{}/CglGomory", CGL_SRC_PATH); + builder.file(format!("{}/CglGomory.cpp", pth)); + extra_include_dirs.push(pth); + } + + { + let pth = format!("{}/CglKnapsackCover", CGL_SRC_PATH); + builder.file(format!("{}/CglKnapsackCover.cpp", pth)); + extra_include_dirs.push(pth); + } + + { + let pth = format!("{}/CglLandP", CGL_SRC_PATH); + builder.file(format!("{}/CglLandP.cpp", pth)); + builder.file(format!("{}/CglLandPMessages.cpp", pth)); + builder.file(format!("{}/CglLandPSimplex.cpp", pth)); + builder.file(format!("{}/CglLandPTabRow.cpp", pth)); + extra_include_dirs.push(pth); + } + + { + let pth = format!("{}/CglMixedIntegerRounding", CGL_SRC_PATH); + builder.file(format!("{}/CglMixedIntegerRounding.cpp", pth)); + extra_include_dirs.push(pth); + } + + { + let pth = format!("{}/CglMixedIntegerRounding2", CGL_SRC_PATH); + builder.file(format!("{}/CglMixedIntegerRounding2.cpp", pth)); + extra_include_dirs.push(pth); + } + + { + let pth = format!("{}/CglOddHole", CGL_SRC_PATH); + builder.file(format!("{}/CglOddHole.cpp", pth)); + extra_include_dirs.push(pth); + } + + { + let pth = format!("{}/CglPreProcess", CGL_SRC_PATH); + builder.file(format!("{}/CglPreProcess.cpp", pth)); + extra_include_dirs.push(pth); + } + + { + let pth = format!("{}/CglProbing", CGL_SRC_PATH); + builder.file(format!("{}/CglProbing.cpp", pth)); + extra_include_dirs.push(pth); + } + + { + let pth = format!("{}/CglRedSplit", CGL_SRC_PATH); + builder.file(format!("{}/CglRedSplit.cpp", pth)); + extra_include_dirs.push(pth); + } + + { + let pth = format!("{}/CglRedSplit2", CGL_SRC_PATH); + builder.file(format!("{}/CglRedSplit2.cpp", pth)); + extra_include_dirs.push(pth); + } + + { + let pth = format!("{}/CglResidualCapacity", CGL_SRC_PATH); + builder.file(format!("{}/CglResidualCapacity.cpp", pth)); + extra_include_dirs.push(pth); + } + + { + let pth = format!("{}/CglSimpleRounding", CGL_SRC_PATH); + builder.file(format!("{}/CglSimpleRounding.cpp", pth)); + extra_include_dirs.push(pth); + } + + { + let pth = format!("{}/CglTwomir", CGL_SRC_PATH); + builder.file(format!("{}/CglTwomir.cpp", pth)); + extra_include_dirs.push(pth); + } + + { + let pth = format!("{}/CglZeroHalf", CGL_SRC_PATH); + builder.file(format!("{}/CglZeroHalf.cpp", pth)); + extra_include_dirs.push(pth); + } + + builder.includes(&extra_include_dirs); + builder.compile("Cgl"); + + extra_include_dirs +} + +const CBC_SRC_PATH: &str = "vendor/Cbc/Cbc/src"; + +const CBC_SRCS: [&str; 67] = [ + "Cbc_C_Interface.cpp", + "CbcCbcParam.cpp", + "CbcSolver.cpp", + "CbcBranchAllDifferent.cpp", + "CbcBranchCut.cpp", + "CbcBranchDecision.cpp", + "CbcBranchDefaultDecision.cpp", + "CbcBranchDynamic.cpp", + "CbcBranchingObject.cpp", + "CbcBranchLotsize.cpp", + "CbcBranchToFixLots.cpp", + "CbcCompareDefault.cpp", + "CbcCompareDepth.cpp", + "CbcCompareEstimate.cpp", + "CbcCompareObjective.cpp", + "CbcConsequence.cpp", + "CbcClique.cpp", + "CbcCountRowCut.cpp", + "CbcCutGenerator.cpp", + "CbcCutModifier.cpp", + "CbcCutSubsetModifier.cpp", + "CbcDummyBranchingObject.cpp", + "CbcEventHandler.cpp", + "CbcFathom.cpp", + "CbcFathomDynamicProgramming.cpp", + "CbcFixVariable.cpp", + "CbcFullNodeInfo.cpp", + "CbcFollowOn.cpp", + "CbcGeneral.cpp", + "CbcGeneralDepth.cpp", + "CbcHeuristic.cpp", + "CbcHeuristicDINS.cpp", + "CbcHeuristicDive.cpp", + "CbcHeuristicDiveCoefficient.cpp", + "CbcHeuristicDiveFractional.cpp", + "CbcHeuristicDiveGuided.cpp", + "CbcHeuristicDiveLineSearch.cpp", + "CbcHeuristicDivePseudoCost.cpp", + "CbcHeuristicDiveVectorLength.cpp", + "CbcHeuristicFPump.cpp", + "CbcHeuristicGreedy.cpp", + "CbcHeuristicLocal.cpp", + "CbcHeuristicPivotAndFix.cpp", + "CbcHeuristicRandRound.cpp", + "CbcHeuristicRENS.cpp", + "CbcHeuristicRINS.cpp", + "CbcHeuristicVND.cpp", + "CbcHeuristicDW.cpp", + "CbcMessage.cpp", + "CbcModel.cpp", + "CbcNode.cpp", + "CbcNodeInfo.cpp", + "CbcNWay.cpp", + "CbcObject.cpp", + "CbcObjectUpdateData.cpp", + "CbcPartialNodeInfo.cpp", + "CbcSimpleInteger.cpp", + "CbcSimpleIntegerDynamicPseudoCost.cpp", + "CbcSimpleIntegerPseudoCost.cpp", + "CbcSOS.cpp", + "CbcStatistics.cpp", + "CbcStrategy.cpp", + "CbcSubProblem.cpp", + "CbcSymmetry.cpp", + "CbcThread.cpp", + "CbcTree.cpp", + "CbcTreeLocal.cpp", +]; + +fn compile_cbc(cgl_include_dirs: &[String]) { + let mut builder = make_builder(); + + builder + .include(COIN_UTILS_PATH) + .include(OSI_SRC_PATH) + .include(CLP_SRC_PATH) + .include(CLP_OSI_SRC_PATH) + .include(CGL_SRC_PATH) + .include(CBC_SRC_PATH); + + builder.includes(cgl_include_dirs); + + for src in CBC_SRCS.iter() { + builder.file(format!("{}/{}", CBC_SRC_PATH, src)); + } + builder.define("CBC_THREAD_SAFE", None); + builder.define("COIN_HAS_CLP", None); + builder.compile("Cbc"); +} + +fn main() { + compile_coin_utils(); + compile_clp(); + compile_osi(); + let cgl_include_dirs = compile_cgl(); + compile_cbc(&cgl_include_dirs); +} diff --git a/coin-or-sys/src/cbc.rs b/coin-or-sys/src/cbc.rs new file mode 100644 index 00000000..71390c44 --- /dev/null +++ b/coin-or-sys/src/cbc.rs @@ -0,0 +1,634 @@ +/* automatically generated by rust-bindgen 0.69.4 */ + +pub type Clp_Simplex = ::std::os::raw::c_void; +pub type clp_callback = ::std::option::Option< + unsafe extern "C" fn( + model: *mut Clp_Simplex, + msgno: ::std::os::raw::c_int, + ndouble: ::std::os::raw::c_int, + dvec: *const f64, + nint: ::std::os::raw::c_int, + ivec: *const ::std::os::raw::c_int, + nchar: ::std::os::raw::c_int, + cvec: *mut *mut ::std::os::raw::c_char, + ), +>; +pub type Sbb_Model = ::std::os::raw::c_void; +pub type Cbc_Model = ::std::os::raw::c_void; +#[doc = " typedef for user call back.\nThe cvec are constructed so don't need to be const"] +pub type sbb_callback = ::std::option::Option< + unsafe extern "C" fn( + model: *mut Sbb_Model, + msgno: ::std::os::raw::c_int, + ndouble: ::std::os::raw::c_int, + dvec: *const f64, + nint: ::std::os::raw::c_int, + ivec: *const ::std::os::raw::c_int, + nchar: ::std::os::raw::c_int, + cvec: *mut *mut ::std::os::raw::c_char, + ), +>; +pub type cbc_callback = ::std::option::Option< + unsafe extern "C" fn( + model: *mut Cbc_Model, + msgno: ::std::os::raw::c_int, + ndouble: ::std::os::raw::c_int, + dvec: *const f64, + nint: ::std::os::raw::c_int, + ivec: *const ::std::os::raw::c_int, + nchar: ::std::os::raw::c_int, + cvec: *mut *mut ::std::os::raw::c_char, + ), +>; +#[doc = " typedef for cbc cut callback osiSolver needs to be an OsiSolverInterface object,\n osiCuts is an OsiCuts object and appdata is a pointer that will be passed to the cut\n generation, you can use it to point to a data structure with information about the original problem,\n for instance"] +pub type cbc_cut_callback = ::std::option::Option< + unsafe extern "C" fn( + osiSolver: *mut ::std::os::raw::c_void, + osiCuts: *mut ::std::os::raw::c_void, + appdata: *mut ::std::os::raw::c_void, + ), +>; +pub type CoinBigIndex = ::std::os::raw::c_int; +pub type wchar_t = ::std::os::raw::c_int; +#[repr(C)] +#[repr(align(16))] +#[derive(Debug, Copy, Clone)] +pub struct max_align_t { + pub __clang_max_align_nonce1: ::std::os::raw::c_longlong, + pub __bindgen_padding_0: u64, + pub __clang_max_align_nonce2: u128, +} +#[test] +fn bindgen_test_layout_max_align_t() { + const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 32usize, + concat!("Size of: ", stringify!(max_align_t)) + ); + assert_eq!( + ::std::mem::align_of::(), + 16usize, + concat!("Alignment of ", stringify!(max_align_t)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__clang_max_align_nonce1) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(max_align_t), + "::", + stringify!(__clang_max_align_nonce1) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__clang_max_align_nonce2) as usize - ptr as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(max_align_t), + "::", + stringify!(__clang_max_align_nonce2) + ) + ); +} +extern "C" { + #[doc = " Current version of Cbc"] + pub fn Cbc_getVersion() -> *const ::std::os::raw::c_char; +} +extern "C" { + #[doc = " @brief Creates an empty problem"] + pub fn Cbc_newModel() -> *mut Cbc_Model; +} +extern "C" { + #[doc = " @brief Sets problem name.\n\n @param model problem object\n @param array string with problem name"] + pub fn Cbc_setProblemName(model: *mut Cbc_Model, array: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " @brief Creates a new column\n\n Creates a new column (variable)\n\n @param model problem object\n @param name variable name\n @param lb column lower bound\n @param ub column upper bound\n @param obj objective function coefficient\n @param isInteger 1 if variable is integral, 0 otherwise\n @param nz number of rows (constraints) where this column appears, can be 0 if constraints will be added later\n @param rows index of rows where this column appears, NULL if rows will be added later\n @param coefs coefficients that this column appears in its rows, NULL if rows will be added later"] + pub fn Cbc_addCol( + model: *mut Cbc_Model, + name: *const ::std::os::raw::c_char, + lb: f64, + ub: f64, + obj: f64, + isInteger: ::std::os::raw::c_char, + nz: ::std::os::raw::c_int, + rows: *mut ::std::os::raw::c_int, + coefs: *mut f64, + ); +} +extern "C" { + #[doc = " @brief Adds a new row\n\n Adds a new row (linear constraint) to the problem\n\n @param model problem object\n @param name constraint name\n @param nz number of variables with non-zero coefficients in this row\n @param cols index of variables that appear in this row\n @param coefs cofficients that that variables appear\n @param sense constraint sense: L if <=, G if >=, E if =, R if ranged and N if free\n @param rhs right hand size"] + pub fn Cbc_addRow( + model: *mut Cbc_Model, + name: *const ::std::os::raw::c_char, + nz: ::std::os::raw::c_int, + cols: *const ::std::os::raw::c_int, + coefs: *const f64, + sense: ::std::os::raw::c_char, + rhs: f64, + ); +} +extern "C" { + #[doc = " @brief Add SOS constraints to the model using row-order matrix"] + pub fn Cbc_addSOS( + model: *mut Cbc_Model, + numRows: ::std::os::raw::c_int, + rowStarts: *const ::std::os::raw::c_int, + colIndices: *const ::std::os::raw::c_int, + weights: *const f64, + type_: ::std::os::raw::c_int, + ); +} +extern "C" { + #[doc = " Loads a problem (the constraints on the\nrows are given by lower and upper bounds). If a pointer is NULL then the\nfollowing values are the default:\n
    \n
  • colub: all columns have upper bound infinity\n
  • collb: all columns have lower bound 0\n
  • rowub: all rows have upper bound infinity\n
  • rowlb: all rows have lower bound -infinity\n
  • obj: all variables have 0 objective coefficient\n
\n\nThe constraint matrix is\ngiven in standard compressed sparse column (without gaps).\n
    \n
  • start[i] stores the starting index of the ith column\n
  • index[k] stores the row index of the kth nonzero element\n
  • value[k] stores the coefficient of the kth nonzero element\n
"] + pub fn Cbc_loadProblem( + model: *mut Cbc_Model, + numcols: ::std::os::raw::c_int, + numrows: ::std::os::raw::c_int, + start: *const CoinBigIndex, + index: *const ::std::os::raw::c_int, + value: *const f64, + collb: *const f64, + colub: *const f64, + obj: *const f64, + rowlb: *const f64, + rowub: *const f64, + ); +} +extern "C" { + #[doc = " @brief Set the name of a column\n\n @param model problem object\n @param iColumn column index\n @param column name"] + pub fn Cbc_setColName(model: *mut Cbc_Model, iColumn: ::std::os::raw::c_int, name: *const ::std::os::raw::c_char); +} +extern "C" { + #[doc = " @brief Set the name of a row\n\n @param model problem object\n @param iRow row index\n @param name row name"] + pub fn Cbc_setRowName(model: *mut Cbc_Model, iRow: ::std::os::raw::c_int, name: *const ::std::os::raw::c_char); +} +extern "C" { + #[doc = " @brief Sets optimization direction\n\n @param model problem object\n @param sense: direction of optimization (1 - minimize, -1 - maximize, 0 - ignore)"] + pub fn Cbc_setObjSense(model: *mut Cbc_Model, sense: f64); +} +extern "C" { + #[doc = " @brief Set the lower bound of a single constraint\n\n @param model problem object\n @param index row index\n @param value new row lower bound"] + pub fn Cbc_setRowLower(model: *mut Cbc_Model, index: ::std::os::raw::c_int, value: f64); +} +extern "C" { + #[doc = " @brief Set the upper bound of a single constraint\n\n @param model problem object\n @param index row index\n @param value new row upper bound"] + pub fn Cbc_setRowUpper(model: *mut Cbc_Model, index: ::std::os::raw::c_int, value: f64); +} +extern "C" { + #[doc = " @brief Set the objective coefficient of a single variable\n\n @param model problem object\n @param index variable index\n @param value new objective function coefficient for this variable"] + pub fn Cbc_setObjCoeff(model: *mut Cbc_Model, index: ::std::os::raw::c_int, value: f64); +} +extern "C" { + #[doc = " @brief Set the lower bound of a single variable\n\n @param model problem object\n @param index variable index\n @param value variable lower bound"] + pub fn Cbc_setColLower(model: *mut Cbc_Model, index: ::std::os::raw::c_int, value: f64); +} +extern "C" { + #[doc = " @brief Set the upper bound of a single variable\n\n @param model problem object\n @param index variable index\n @param value new variable upper bound"] + pub fn Cbc_setColUpper(model: *mut Cbc_Model, index: ::std::os::raw::c_int, value: f64); +} +extern "C" { + #[doc = " @brief Set this variable to be continuous\n\n @param model problem object\n @param iColumn column index"] + pub fn Cbc_setContinuous(model: *mut Cbc_Model, iColumn: ::std::os::raw::c_int); +} +extern "C" { + #[doc = " @brief Set this variable to be integer\n\n @param model problem object\n @param iColumn column index"] + pub fn Cbc_setInteger(model: *mut Cbc_Model, iColumn: ::std::os::raw::c_int); +} +extern "C" { + #[doc = " @brief Cbc_Model destructor"] + pub fn Cbc_deleteModel(model: *mut Cbc_Model); +} +extern "C" { + #[doc = " @brief Enter initial feasible solution\n\n Enter an initial feasible solution. Only the non-zero main\n binary/integer decision variables need to be informed.\n Auxiliary and/or continuous variables are computed\n automatically.\n\n @param model problem object\n @param count number of variables\n @param colNames names of variables\n @param colValues variable values\n"] + pub fn Cbc_setMIPStart( + model: *mut Cbc_Model, + count: ::std::os::raw::c_int, + colNames: *mut *const ::std::os::raw::c_char, + colValues: *const f64, + ); +} +extern "C" { + #[doc = " @brief Enter initial feasible solution\n\n Enter an initial feasible solution. Only the non-zero main\n binary/integer decision variables need to be informed.\n Auxiliary and/or continuous variables are computed\n automatically. Same as setMIPStart but using variable indexes.\n\n @param model problem object\n @param count number of variables\n @param colIdxs indexes of variables\n @param colValues variable values\n"] + pub fn Cbc_setMIPStartI( + model: *mut Cbc_Model, + count: ::std::os::raw::c_int, + colIdxs: *const ::std::os::raw::c_int, + colValues: *const f64, + ); +} +extern "C" { + #[doc = " @brief Creates a copy of the current model\n\n @param model problem object\n @return model copy"] + pub fn Cbc_clone(model: *mut Cbc_Model) -> *mut Cbc_Model; +} +extern "C" { + #[doc = " @brief Queries problem name\n\n @param model problem object\n @param maxNumberCharacters space in string array\n @param array string where problem name will be saved"] + pub fn Cbc_problemName( + model: *mut Cbc_Model, + maxNumberCharacters: ::std::os::raw::c_int, + array: *mut ::std::os::raw::c_char, + ); +} +extern "C" { + #[doc = " @brief Number of nonzero elements in constraint matrix\n\n @param model problem object\n @return number of non-zero entries in constraint matrix"] + pub fn Cbc_getNumElements(model: *mut Cbc_Model) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " @brief Number of variables in the model\n @param model problem object\n @return number of columns (variables)"] + pub fn Cbc_getNumCols(model: *mut Cbc_Model) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " @brief Number of integer variables in the model\n\n @param model problem object\n @return number of integer variables in this model"] + pub fn Cbc_getNumIntegers(model: *mut Cbc_Model) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " Number of constraints in the model\n @param model problem object\n @return number of rows (constraints) in the model"] + pub fn Cbc_getNumRows(model: *mut Cbc_Model) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " @brief Queries row name\n\n @param model problem object\n @param row index\n @param name string where row name will be stored\n @param string where row name will be stored"] + pub fn Cbc_getRowName( + model: *mut Cbc_Model, + iRow: ::std::os::raw::c_int, + name: *mut ::std::os::raw::c_char, + maxLength: usize, + ); +} +extern "C" { + #[doc = " Queries column name\n\n @param model problem object\n @param iColumn column index\n @param name where name will be stored\n @param maxLength maximum length of name string"] + pub fn Cbc_getColName( + model: *mut Cbc_Model, + iColumn: ::std::os::raw::c_int, + name: *mut ::std::os::raw::c_char, + maxLength: usize, + ); +} +extern "C" { + #[doc = " @brief Number of non-zero entries in a row\n\n @param model problem object\n @param row row index\n @return number of non-zero entries in row"] + pub fn Cbc_getRowNz(model: *mut Cbc_Model, row: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " @brief Indices of variables that appear on a row\n\n @param model problem object\n @param row row index\n @return vector with indexes of columns that appear on this row"] + pub fn Cbc_getRowIndices(model: *mut Cbc_Model, row: ::std::os::raw::c_int) -> *const ::std::os::raw::c_int; +} +extern "C" { + #[doc = " @brief Coefficients of variables that appear on this row\n\n @param model problem object\n @param row row index\n @return coefficients of variables that appear on this row"] + pub fn Cbc_getRowCoeffs(model: *mut Cbc_Model, row: ::std::os::raw::c_int) -> *const f64; +} +extern "C" { + #[doc = " @brief Number of non-zero entries in a column\n\n @param model problem object\n @param col column index\n @return numbef of rows that this column appears"] + pub fn Cbc_getColNz(model: *mut Cbc_Model, col: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " @brief Indices of rows that a column appears\n\n @param model problem object\n @param col column index\n @return indices of rows that this column appears"] + pub fn Cbc_getColIndices(model: *mut Cbc_Model, col: ::std::os::raw::c_int) -> *const ::std::os::raw::c_int; +} +extern "C" { + #[doc = " @brief Coefficients that a column appear in rows\n\n @param model problem object\n @param col column index\n @return coefficients of this column in rows"] + pub fn Cbc_getColCoeffs(model: *mut Cbc_Model, col: ::std::os::raw::c_int) -> *const f64; +} +extern "C" { + #[doc = " @brief Right hand side of a row\n\n @param model problem object\n @param row row index\n @return row right hand side"] + pub fn Cbc_getRowRHS(model: *mut Cbc_Model, row: ::std::os::raw::c_int) -> f64; +} +extern "C" { + #[doc = " @brief Sense a row\n @param model problem object\n @param row row index\n @return row sense: E for =, L for <=, G for >= and R for ranged row"] + pub fn Cbc_getRowSense(model: *mut Cbc_Model, row: ::std::os::raw::c_int) -> ::std::os::raw::c_char; +} +extern "C" { + #[doc = " @brief Direction of optimization\n\n @param model problem object\n @return Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore)"] + pub fn Cbc_getObjSense(model: *mut Cbc_Model) -> f64; +} +extern "C" { + #[doc = " @brief Constraint lower bounds\n\n @param model problem object\n @return vector with lower bounds of constraints"] + pub fn Cbc_getRowLower(model: *mut Cbc_Model) -> *const f64; +} +extern "C" { + #[doc = " @brief Constraint upper bounds\n\n @param model problem object\n @return constraint upper bounds"] + pub fn Cbc_getRowUpper(model: *mut Cbc_Model) -> *const f64; +} +extern "C" { + #[doc = " @brief Objective vector\n\n @param model problem object\n @return vector with coefficients of variables in the objective function"] + pub fn Cbc_getObjCoefficients(model: *mut Cbc_Model) -> *const f64; +} +extern "C" { + #[doc = " @brief Variable lower bounds\n\n @param model problem object\n @return vector with lower bounds of variables"] + pub fn Cbc_getColLower(model: *mut Cbc_Model) -> *const f64; +} +extern "C" { + #[doc = " @brief Variable upper bounds\n\n @param model problem object\n @return vector with column upper bounds"] + pub fn Cbc_getColUpper(model: *mut Cbc_Model) -> *const f64; +} +extern "C" { + #[doc = " @brief Determine whether the ith variable is integer restricted\n\n @param model problem object\n @param i variable index\n @return 1 if variable is integer, 0 otherwise"] + pub fn Cbc_isInteger(model: *mut Cbc_Model, i: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " @brief Read an mps file from the given filename\n\n @param model problem object\n @param fileName file name"] + pub fn Cbc_readMps(model: *mut Cbc_Model, filename: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " @brief Read an lp file from the given filename\n\n @param model problem object\n @param fileName file name"] + pub fn Cbc_readLp(model: *mut Cbc_Model, filename: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " @brief Write an mps file from the given filename\n\n @param model problem object\n @param fileName file name"] + pub fn Cbc_writeMps(model: *mut Cbc_Model, filename: *const ::std::os::raw::c_char); +} +extern "C" { + #[doc = " @brief Write an lp file from the given filename\n\n @param model problem object\n @param fileName file name"] + pub fn Cbc_writeLp(model: *mut Cbc_Model, filename: *const ::std::os::raw::c_char); +} +extern "C" { + #[doc = " Provide an initial feasible solution to accelerate branch-and-bound\nNote that feasibility of the solution is *not* verified."] + pub fn Cbc_setInitialSolution(model: *mut Cbc_Model, sol: *const f64); +} +extern "C" { + #[doc = " \"Column start\" vector of constraint matrix. Same format as Cbc_loadProblem()"] + pub fn Cbc_getVectorStarts(model: *mut Cbc_Model) -> *const CoinBigIndex; +} +extern "C" { + #[doc = " \"Row index\" vector of constraint matrix"] + pub fn Cbc_getIndices(model: *mut Cbc_Model) -> *const ::std::os::raw::c_int; +} +extern "C" { + #[doc = " Coefficient vector of constraint matrix"] + pub fn Cbc_getElements(model: *mut Cbc_Model) -> *const f64; +} +extern "C" { + #[doc = " Maximum lenght of a row or column name"] + pub fn Cbc_maxNameLength(model: *mut Cbc_Model) -> usize; +} +extern "C" { + #[doc = " Print the model"] + pub fn Cbc_printModel(model: *mut Cbc_Model, argPrefix: *const ::std::os::raw::c_char); +} +extern "C" { + #[doc = "@name Solver parameters */\n/**@{*/\n/** Set parameter \"name\" to value \"value\". Note that this\n translates directly to using \"-name value\" as a\n command-line argument to Cbc."] + pub fn Cbc_setParameter( + model: *mut Cbc_Model, + name: *const ::std::os::raw::c_char, + value: *const ::std::os::raw::c_char, + ); +} +extern "C" { + #[doc = " returns the allowable gap"] + pub fn Cbc_getAllowableGap(model: *mut Cbc_Model) -> f64; +} +extern "C" { + #[doc = " sets the allowable gap"] + pub fn Cbc_setAllowableGap(model: *mut Cbc_Model, allowedGap: f64); +} +extern "C" { + #[doc = " returns the allowable fraction gap"] + pub fn Cbc_getAllowableFractionGap(model: *mut Cbc_Model) -> f64; +} +extern "C" { + #[doc = " sets the allowable fraction gap"] + pub fn Cbc_setAllowableFractionGap(model: *mut Cbc_Model, allowedFracionGap: f64); +} +extern "C" { + #[doc = " returns the allowable percentage gap"] + pub fn Cbc_getAllowablePercentageGap(model: *mut Cbc_Model) -> f64; +} +extern "C" { + #[doc = " sets the allowable percentage gap"] + pub fn Cbc_setAllowablePercentageGap(model: *mut Cbc_Model, allowedPercentageGap: f64); +} +extern "C" { + #[doc = " returns the time limit for the search process"] + pub fn Cbc_getMaximumSeconds(model: *mut Cbc_Model) -> f64; +} +extern "C" { + #[doc = " sets the time limit for the search process"] + pub fn Cbc_setMaximumSeconds(model: *mut Cbc_Model, maxSeconds: f64); +} +extern "C" { + #[doc = " returns the maximum number of nodes that can be explored in the search tree"] + pub fn Cbc_getMaximumNodes(model: *mut Cbc_Model) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " sets the maximum number of nodes that can be explored in the search tree"] + pub fn Cbc_setMaximumNodes(model: *mut Cbc_Model, maxNodes: ::std::os::raw::c_int); +} +extern "C" { + #[doc = " returns solution limit for the search process"] + pub fn Cbc_getMaximumSolutions(model: *mut Cbc_Model) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " sets a solution limit as a stopping criterion"] + pub fn Cbc_setMaximumSolutions(model: *mut Cbc_Model, maxSolutions: ::std::os::raw::c_int); +} +extern "C" { + #[doc = " returns the current log leven"] + pub fn Cbc_getLogLevel(model: *mut Cbc_Model) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " sets the log level"] + pub fn Cbc_setLogLevel(model: *mut Cbc_Model, logLevel: ::std::os::raw::c_int); +} +extern "C" { + #[doc = " returns the cutoff"] + pub fn Cbc_getCutoff(model: *mut Cbc_Model) -> f64; +} +extern "C" { + #[doc = " sets the cutoff"] + pub fn Cbc_setCutoff(model: *mut Cbc_Model, cutoff: f64); +} +extern "C" { + #[doc = "@}*/\n/**@name Message handling. Call backs are handled by ONE function */\n/**@{*/\n/** Pass in Callback function.\nMessage numbers up to 1000000 are Clp, Coin ones have 1000000 added"] + pub fn Cbc_registerCallBack(model: *mut Cbc_Model, userCallBack: cbc_callback); +} +extern "C" { + #[doc = " Unset Callback function"] + pub fn Cbc_clearCallBack(model: *mut Cbc_Model); +} +extern "C" { + pub fn Cbc_addCutCallback( + model: *mut Cbc_Model, + cutcb: cbc_cut_callback, + name: *const ::std::os::raw::c_char, + appData: *mut ::std::os::raw::c_void, + ); +} +extern "C" { + #[doc = "@name Solving the model */\n/**@{"] + pub fn Cbc_solve(model: *mut Cbc_Model) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " @brief Best feasible solution vector\n\n @param model problem object\n @return vector with best solution found"] + pub fn Cbc_getColSolution(model: *mut Cbc_Model) -> *const f64; +} +extern "C" { + #[doc = " @brief Best known bound on the optimal objective value\n\n @param model problem object\n @return best possible cost (lower bound)"] + pub fn Cbc_getBestPossibleObjValue(model: *mut Cbc_Model) -> f64; +} +extern "C" { + #[doc = " @brief Best integer feasible solution\n\n Best integer feasible solution or NULL if no integer feas sol found\n\n @param model problem object\n @return vector with the best solution found or NULL if no feasible solution was found"] + pub fn Cbc_bestSolution(model: *mut Cbc_Model) -> *mut f64; +} +extern "C" { + #[doc = " @brief number of integer feasible solution saved\n\n @param model problem object\n @return number of saved solutions"] + pub fn Cbc_numberSavedSolutions(model: *mut Cbc_Model) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " @brief Vector with the i-th saved solution\n\n @param model problem object\n @param whichSol index of the solution to be retrieved\n @return vector with integer feasible solution"] + pub fn Cbc_savedSolution(model: *mut Cbc_Model, whichSol: ::std::os::raw::c_int) -> *const f64; +} +extern "C" { + #[doc = " @brief Cost of the whichSol solution\n\n @param model problem object\n @param whichSol solution index\n @return solution cost"] + pub fn Cbc_savedSolutionObj(model: *mut Cbc_Model, whichSol: ::std::os::raw::c_int) -> f64; +} +extern "C" { + #[doc = " @brief Queries vector of reduced costs\n\n @param model problem object\n @return reduced cost vector"] + pub fn Cbc_getReducedCost(model: *mut Cbc_Model) -> *const f64; +} +extern "C" { + #[doc = " If optimization was abandoned due to numerical difficulties\n\n @param model problem object\n @return 1 if numerical difficulties interrupted the optimization, 0 otherwise"] + pub fn Cbc_isAbandoned(model: *mut Cbc_Model) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " @brief If the optimal solution was found\n\n @param model problem object\n @return 1 if optimal solution was found, 0 otherwise"] + pub fn Cbc_isProvenOptimal(model: *mut Cbc_Model) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " @brief If infeasibility was proven\n\n If model is infeasible, please note that infeasibility can also be declared\n if cutoff is informed and no solution better than the cutoff exists.\n\n @param model problem object\n @return 1 if model is infeasible, 0 otherwise"] + pub fn Cbc_isProvenInfeasible(model: *mut Cbc_Model) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " @brief Is continuous model unbounded ?\n\n @param model problem object\n @return 1 if model is unbounded, 0 otherwise"] + pub fn Cbc_isContinuousUnbounded(model: *mut Cbc_Model) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " Objective value of best feasible solution\n\n @param model problem object\n @return cost of the best solution found"] + pub fn Cbc_getObjValue(model: *mut Cbc_Model) -> f64; +} +extern "C" { + #[doc = " @brief Final optimization status\n\n Returns the optimization status. For more info check function\n isProvenOptimal, isProvenInfeasible, etc. Check also secondary status.\n Possible status are:\n\n -1 before branchAndBound\n 0 finished - check isProvenOptimal or isProvenInfeasible to see if solution found (or check value of best solution)\n 1 stopped - on maxnodes, maxsols, maxtime\n 2 execution abandoned due to numerical dificulties\n 5 user programmed interruption\n\n @param model problem object\n @return problem status"] + pub fn Cbc_status(model: *mut Cbc_Model) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " @brief Secondary status of problem\n\n Returns additional information regarding the optimization status\n\n -1 unset (status_ will also be -1)\n 0 search completed with solution\n 1 linear relaxation not feasible (or worse than cutoff)\n 2 stopped on gap\n 3 stopped on nodes\n 4 stopped on time\n 5 stopped on user event\n 6 stopped on solutions\n 7 linear relaxation unbounded\n 8 stopped on iteration limit\n\n @model problem object\n @return optimization status"] + pub fn Cbc_secondaryStatus(model: *mut Cbc_Model) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " Sum of primal infeasibilities"] + pub fn Cbc_sumPrimalInfeasibilities(model: *mut Cbc_Model) -> f64; +} +extern "C" { + #[doc = " Number of primal infeasibilities"] + pub fn Cbc_numberPrimalInfeasibilities(model: *mut Cbc_Model) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " Just check solution (for external use) - sets sum of\ninfeasibilities etc"] + pub fn Cbc_checkSolution(model: *mut Cbc_Model); +} +extern "C" { + #[doc = " Number of iterations"] + pub fn Cbc_getIterationCount(model: *mut Cbc_Model) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " Node limit reached?"] + pub fn Cbc_isNodeLimitReached(model: *mut Cbc_Model) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " Time limit reached?"] + pub fn Cbc_isSecondsLimitReached(model: *mut Cbc_Model) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " Solution limit reached?"] + pub fn Cbc_isSolutionLimitReached(model: *mut Cbc_Model) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " Are there numerical difficulties (for initialSolve) ?"] + pub fn Cbc_isInitialSolveAbandoned(model: *mut Cbc_Model) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " Is optimality proven (for initialSolve) ?"] + pub fn Cbc_isInitialSolveProvenOptimal(model: *mut Cbc_Model) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " Is primal infeasiblity proven (for initialSolve) ?"] + pub fn Cbc_isInitialSolveProvenPrimalInfeasible(model: *mut Cbc_Model) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " \"row\" solution\n This is the vector A*x, where A is the constraint matrix\n and x is the current solution."] + pub fn Cbc_getRowActivity(model: *mut Cbc_Model) -> *const f64; +} +extern "C" { + #[doc = " Number of nodes explored in B&B tree"] + pub fn Cbc_getNodeCount(model: *mut Cbc_Model) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " Print the solution"] + pub fn Cbc_printSolution(model: *mut Cbc_Model); +} +extern "C" { + #[doc = " @brief Returns number of cols in OsiSolverInterface object"] + pub fn Osi_getNumCols(osi: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " @brief Returns column name in OsiSolverInterface object"] + pub fn Osi_getColName( + osi: *mut ::std::os::raw::c_void, + i: ::std::os::raw::c_int, + name: *mut ::std::os::raw::c_char, + maxLen: ::std::os::raw::c_int, + ); +} +extern "C" { + #[doc = " @brief Returns column lower bounds in OsiSolverInterface object"] + pub fn Osi_getColLower(osi: *mut ::std::os::raw::c_void) -> *const f64; +} +extern "C" { + #[doc = " @brief Returns column upper bounds in OsiSolverInterface object"] + pub fn Osi_getColUpper(osi: *mut ::std::os::raw::c_void) -> *const f64; +} +extern "C" { + #[doc = " @brief Returns integrality information for columns in OsiSolverInterface object"] + pub fn Osi_isInteger(osi: *mut ::std::os::raw::c_void, col: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " @brief Returns number of rows in OsiSolverInterface object"] + pub fn Osi_getNumRows(osi: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn Osi_getRowNz(osi: *mut ::std::os::raw::c_void, row: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " @brief Indices of variables that appear on a row"] + pub fn Osi_getRowIndices( + osi: *mut ::std::os::raw::c_void, + row: ::std::os::raw::c_int, + ) -> *const ::std::os::raw::c_int; +} +extern "C" { + #[doc = " @brief Coefficients of variables that appear on this row\n\n @param model problem object\n @param row row index\n @return coefficients of variables that appear on this row"] + pub fn Osi_getRowCoeffs(osi: *mut ::std::os::raw::c_void, row: ::std::os::raw::c_int) -> *const f64; +} +extern "C" { + #[doc = " @brief Right hand side of a row\n\n @param model problem object\n @param row row index\n @return row right hand side"] + pub fn Osi_getRowRHS(osi: *mut ::std::os::raw::c_void, row: ::std::os::raw::c_int) -> f64; +} +extern "C" { + #[doc = " @brief Sense a row\n @param model problem object\n @param row row index\n @return row sense: E for =, L for <=, G for >= and R for ranged row"] + pub fn Osi_getRowSense(osi: *mut ::std::os::raw::c_void, row: ::std::os::raw::c_int) -> ::std::os::raw::c_char; +} +extern "C" { + #[doc = " @brief Returns solution vector in OsiSolverInterface object"] + pub fn Osi_getColSolution(osi: *mut ::std::os::raw::c_void) -> *const f64; +} +extern "C" { + #[doc = " adds a row cut (used in callback)"] + pub fn OsiCuts_addRowCut( + osiCuts: *mut ::std::os::raw::c_void, + nz: ::std::os::raw::c_int, + idx: *const ::std::os::raw::c_int, + coef: *const f64, + sense: ::std::os::raw::c_char, + rhs: f64, + ); +} diff --git a/clp-sys/src/bindings.rs b/coin-or-sys/src/clp.rs similarity index 100% rename from clp-sys/src/bindings.rs rename to coin-or-sys/src/clp.rs diff --git a/coin-or-sys/src/lib.rs b/coin-or-sys/src/lib.rs new file mode 100644 index 00000000..05c80937 --- /dev/null +++ b/coin-or-sys/src/lib.rs @@ -0,0 +1,53 @@ +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] + +pub mod clp { + include!("clp.rs"); +} + +pub mod cbc { + include!("cbc.rs"); +} + +#[cfg(test)] +mod tests { + use super::cbc::{Cbc_deleteModel, Cbc_getVersion, Cbc_newModel}; + use super::clp::{Clp_Version, Clp_deleteModel, Clp_newModel}; + + #[test] + fn test_clp_version() { + unsafe { + let c_buf = Clp_Version(); + let c_str = std::ffi::CStr::from_ptr(c_buf); + let version = c_str.to_str().unwrap(); + println!("{}", version); + } + } + + #[test] + fn test_clp_model() { + unsafe { + let model = Clp_newModel(); + Clp_deleteModel(model); + } + } + + #[test] + fn test_cbc_version() { + unsafe { + let c_buf = Cbc_getVersion(); + let c_str = std::ffi::CStr::from_ptr(c_buf); + let version = c_str.to_str().unwrap(); + println!("{}", version); + } + } + + #[test] + fn test_cbc_model() { + unsafe { + let model = Cbc_newModel(); + Cbc_deleteModel(model); + } + } +} diff --git a/coin-or-sys/vendor/Cbc b/coin-or-sys/vendor/Cbc new file mode 160000 index 00000000..d916443d --- /dev/null +++ b/coin-or-sys/vendor/Cbc @@ -0,0 +1 @@ +Subproject commit d916443dfc1262f1e346418b7a76a07540f1e8b2 diff --git a/coin-or-sys/vendor/Cgl b/coin-or-sys/vendor/Cgl new file mode 160000 index 00000000..a01f62e4 --- /dev/null +++ b/coin-or-sys/vendor/Cgl @@ -0,0 +1 @@ +Subproject commit a01f62e4fa70f5308784cc4cc0b3947f7d2b52b6 diff --git a/clp-sys/vendor/Clp b/coin-or-sys/vendor/Clp similarity index 100% rename from clp-sys/vendor/Clp rename to coin-or-sys/vendor/Clp diff --git a/clp-sys/vendor/CoinUtils b/coin-or-sys/vendor/CoinUtils similarity index 100% rename from clp-sys/vendor/CoinUtils rename to coin-or-sys/vendor/CoinUtils diff --git a/coin-or-sys/vendor/Osi b/coin-or-sys/vendor/Osi new file mode 160000 index 00000000..2997cda8 --- /dev/null +++ b/coin-or-sys/vendor/Osi @@ -0,0 +1 @@ +Subproject commit 2997cda8e85ccc6712c4b05404e7aa70500e422f diff --git a/pywr-core/Cargo.toml b/pywr-core/Cargo.toml index 04097ff3..8ff77f88 100644 --- a/pywr-core/Cargo.toml +++ b/pywr-core/Cargo.toml @@ -21,7 +21,7 @@ num = { workspace = true } float-cmp = { workspace = true } hdf5 = { workspace = true } csv = { workspace = true } -clp-sys = { path = "../clp-sys", version = "0.1.0" } +coin-or-sys = { path = "../coin-or-sys", version = "0.1.0" } ipm-ocl = { path = "../ipm-ocl", optional = true } ipm-simd = { path = "../ipm-simd", optional = true } tracing = { workspace = true } @@ -30,7 +30,7 @@ nalgebra = "0.32.3" chrono = { workspace = true } polars = { workspace = true } -pyo3 = { workspace = true, features = ["chrono"] } +pyo3 = { workspace = true, features = ["chrono", "macros"] } rayon = "1.6.1" diff --git a/pywr-core/src/solvers/clp/mod.rs b/pywr-core/src/solvers/clp/mod.rs index 414c9dd1..93f67dd5 100644 --- a/pywr-core/src/solvers/clp/mod.rs +++ b/pywr-core/src/solvers/clp/mod.rs @@ -7,7 +7,7 @@ use crate::solvers::{Solver, SolverFeatures, SolverTimings}; use crate::state::State; use crate::timestep::Timestep; use crate::PywrError; -use clp_sys::*; +use coin_or_sys::clp::*; use libc::{c_double, c_int}; pub use settings::{ClpSolverSettings, ClpSolverSettingsBuilder}; use std::ffi::CString;