1pub mod error;
32pub use error::SolverError;
33pub use error::MpsError;
34#[doc(hidden)]
35pub mod presolve;
36pub mod sparse;
37pub mod problem;
38pub(crate) mod simplex;
39#[cfg(test)]
45#[allow(dead_code)]
46pub(crate) mod io;
47pub(crate) mod basis;
48pub mod tolerances;
49pub mod options;
50pub use options::{
51 BranchingStrategy, DualPricing, GlobalOptimizationConfig, LpWarmStart, MipBranching, MipConfig,
52 SolverOptions, Tolerance, WarmStartBasis,
53};
54pub mod qp;
55pub mod mip;
56pub mod lp;
57#[doc(hidden)]
58pub mod linalg;
59
60#[cfg(test)]
61pub(crate) mod test_kkt;
62
63#[cfg(test)]
69pub(crate) mod peak_alloc {
70 use std::alloc::{GlobalAlloc, Layout, System};
71 use std::cell::Cell;
72
73 thread_local! {
74 static CURRENT: Cell<isize> = const { Cell::new(0) };
75 }
76
77 #[inline]
78 fn update(delta: isize) {
79 CURRENT.with(|c| c.set(c.get() + delta));
80 }
81
82 pub struct TrackingAlloc;
83
84 unsafe impl GlobalAlloc for TrackingAlloc {
85 unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
86 let ptr = System.alloc(layout);
87 if !ptr.is_null() {
88 update(layout.size() as isize);
89 }
90 ptr
91 }
92 unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
93 let ptr = System.alloc_zeroed(layout);
94 if !ptr.is_null() {
95 update(layout.size() as isize);
96 }
97 ptr
98 }
99 unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
100 System.dealloc(ptr, layout);
101 update(-(layout.size() as isize));
102 }
103 unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
104 let new_ptr = System.realloc(ptr, layout, new_size);
105 if !new_ptr.is_null() {
106 update(new_size as isize - layout.size() as isize);
107 }
108 new_ptr
109 }
110 }
111}
112
113#[cfg(test)]
114#[global_allocator]
115static TEST_ALLOC: peak_alloc::TrackingAlloc = peak_alloc::TrackingAlloc;
116
117pub use sparse::CscMatrix;
119pub use problem::{SolveRoute, SolveStats, SolveStatus};
120pub use problem::certificate::{
121 BoundGapCertificate, FarkasCertificate, IncompleteReason, NotProven, OptimalCertificate,
122 SolveOutcome, UnboundedRayCertificate,
123};
124pub use qp::certificate::prove_optimal;
125pub use qp::{solve_qp, solve_qp_global, solve_qp_with, QpProblem, SolverResult, QpWarmStart};
126pub use mip::{
127 solve_milp, solve_milp_with_stats, solve_miqp, solve_miqp_with_stats, MilpProblem,
128 MipProblemError, MipStats, MiqpProblem,
129};
130pub use lp::solve_lp_with;
131pub use simplex::{solve, solve_with};
132
133#[doc(hidden)]
136pub mod bound_flip {
137 pub use crate::simplex::dual_advanced::bound_flip::{
138 bfrt_flip_invocations, bfrt_select_entering, reset_bfrt_flip_invocations,
139 BfrtResult, ColBound,
140 };
141}
142pub use qp::{diagnose, DiagnosticReport, DiagnosticWarning, DiagnosticCode, Severity, ProblemInfo};
143
144#[cfg(test)]
150pub(crate) struct ScopedDisable<D: Fn()> {
151 restore: D,
152}
153
154#[cfg(test)]
155impl<D: Fn()> ScopedDisable<D> {
156 pub(crate) fn new<E: Fn()>(enable: E, restore: D) -> Self {
157 enable();
158 ScopedDisable { restore }
159 }
160}
161
162#[cfg(test)]
163impl<D: Fn()> Drop for ScopedDisable<D> {
164 fn drop(&mut self) {
165 (self.restore)();
166 }
167}
168
169#[doc(hidden)]
175pub fn apply_lp_primal_guard(
176 result: crate::problem::SolverResult,
177 problem: &crate::problem::LpProblem,
178) -> crate::problem::SolverResult {
179 crate::qp::certificate::guard_lp_optimal(result, problem)
180}