-
Notifications
You must be signed in to change notification settings - Fork 22
Expand file tree
/
Copy pathcallback.rs
More file actions
163 lines (150 loc) · 5.32 KB
/
callback.rs
File metadata and controls
163 lines (150 loc) · 5.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
//! # User Callbacks in HiGHS
use std::ffi::{c_int, c_void};
/// User callbacks while solving
pub trait Callback {
/// The main callback routine
fn callback(&mut self, context: CallbackOuterContext<'_>) -> CallbackReturn;
}
/// The context of a user callback
pub struct CallbackOuterContext<'a> {
data: &'a highs_sys::HighsCallbackDataOut,
callback_type: c_int,
}
// Applicable in all contexts
impl<'a> CallbackOuterContext<'a> {
/// Gets the inner callback context
pub fn inner(self) -> CallbackType<'a> {
match self.callback_type {
highs_sys::kHighsCallbackLogging => CallbackType::Logging(CallbackContext {
data: self.data,
_ctx: CbCtxLogging,
}),
highs_sys::kHighsCallbackSimplexInterrupt => {
CallbackType::SimplexInterrupt(CallbackContext {
data: self.data,
_ctx: CbCtxSimplexInterrupt,
})
}
highs_sys::kHighsCallbackIpmInterrupt => CallbackType::IpmInterrupt(CallbackContext {
data: self.data,
_ctx: CbCtxIpmInterrupt,
}),
highs_sys::kHighsCallbackMipSolution => CallbackType::MipSolution(CallbackContext {
data: self.data,
_ctx: CbCtxMipSolution,
}),
highs_sys::kHighsCallbackMipImprovingSolution => {
CallbackType::MipImprovingSolution(CallbackContext {
data: self.data,
_ctx: CbCtxMipImprovingSolution,
})
}
highs_sys::kHighsCallbackMipLogging => CallbackType::MipLogging(CallbackContext {
data: self.data,
_ctx: CbCtxMipLogging,
}),
highs_sys::kHighsCallbackMipInterrupt => CallbackType::MipInterrupt(CallbackContext {
data: self.data,
_ctx: CbCtxMipInterrupt,
}),
highs_sys::kHighsCallbackMipGetCutPool => {
CallbackType::MipGetCutPool(CallbackContext {
data: self.data,
_ctx: CbCtxMipGetCutPool,
})
}
highs_sys::kHighsCallbackMipDefineLazyConstraints => {
CallbackType::MipDefineLazyConstraints(CallbackContext {
data: self.data,
_ctx: CbCtxMipDefineLazyConstraints,
})
}
_ => unreachable!(),
}
}
/// Gets the running time of the solver
pub fn get_running_time(&self) -> f64 {
self.data.running_time
}
}
/// The type of callback
pub enum CallbackType<'a> {
/// Logging callback
Logging(CallbackContext<'a, CbCtxLogging>),
/// Simplex interrupt callback
SimplexInterrupt(CallbackContext<'a, CbCtxSimplexInterrupt>),
/// IPM interrupt callback
IpmInterrupt(CallbackContext<'a, CbCtxIpmInterrupt>),
/// Found a MIP solution
MipSolution(CallbackContext<'a, CbCtxMipSolution>),
/// Found an improving MIP solution
MipImprovingSolution(CallbackContext<'a, CbCtxMipImprovingSolution>),
/// MIP logging callback
MipLogging(CallbackContext<'a, CbCtxMipLogging>),
/// MIP interrupt callback
MipInterrupt(CallbackContext<'a, CbCtxMipInterrupt>),
/// MIP get cut pool callback
MipGetCutPool(CallbackContext<'a, CbCtxMipGetCutPool>),
/// MIP define lazy constraints callback
MipDefineLazyConstraints(CallbackContext<'a, CbCtxMipDefineLazyConstraints>),
}
/// Logging callback context
pub struct CbCtxLogging;
/// Simplex interrupt callback context
pub struct CbCtxSimplexInterrupt;
/// IPM interrupt callback context
pub struct CbCtxIpmInterrupt;
/// MIP solution callback context
pub struct CbCtxMipSolution;
/// MIP improving solution callback context
pub struct CbCtxMipImprovingSolution;
/// MIP logging callback context
pub struct CbCtxMipLogging;
/// MIP interrupt callback context
pub struct CbCtxMipInterrupt;
/// MIP get cut pool callback context
pub struct CbCtxMipGetCutPool;
/// MIP define lazy constraints callback context
pub struct CbCtxMipDefineLazyConstraints;
/// An inner callback context
pub struct CallbackContext<'a, Ctx> {
data: &'a highs_sys::HighsCallbackDataOut,
_ctx: Ctx,
}
// Applicable in all contexts
impl<Ctx> CallbackContext<'_, Ctx> {
/// Gets the running time of the solver
pub fn get_running_time(&self) -> f64 {
self.data.running_time
}
}
/// The return type for a user callback
#[derive(Debug, Default)]
pub struct CallbackReturn {
user_interrupt: bool,
}
impl CallbackReturn {
/// Sets the user interrupt value
pub fn set_interrupt(&mut self, interrupt: bool) -> &mut Self {
self.user_interrupt = interrupt;
self
}
}
pub(crate) struct UserCallbackData<'a>(pub &'a mut dyn Callback);
pub(crate) unsafe extern "C" fn callback(
callback_type: c_int,
_message: *const i8,
out_data: *const highs_sys::HighsCallbackDataOut,
in_data: *mut highs_sys::HighsCallbackDataIn,
user_callback_data: *mut c_void,
) {
let user_callback_data = &mut *user_callback_data.cast::<UserCallbackData>();
let ctx = CallbackOuterContext {
data: &*out_data,
callback_type,
};
let res = user_callback_data.0.callback(ctx);
if res.user_interrupt {
(*in_data).user_interrupt = 1;
}
}