| ︙ | | | ︙ | |
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
*/
//! An asynchronous parallel bundle solver.
use crossbeam::channel::{select, unbounded as channel, Receiver, Sender};
use log::{debug, info};
use num_cpus;
use num_traits::Float;
use std::sync::Arc;
use std::time::Instant;
use threadpool::ThreadPool;
use crate::{DVector, Real};
use super::masterprocess::{self, MasterConfig, MasterProcess, MasterResponse};
use crate::master::{self, MasterProblem};
use crate::problem::{EvalResult, FirstOrderProblem, Update, UpdateState};
use crate::terminator::{StandardTerminatable, StandardTerminator, Terminator};
use crate::weighter::{HKWeightable, HKWeighter, Weighter};
|
<
|
|
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
*/
//! An asynchronous parallel bundle solver.
use crossbeam::channel::{select, unbounded as channel, Receiver, Sender};
use log::{debug, info};
use num_cpus;
use std::sync::Arc;
use std::time::Instant;
use threadpool::ThreadPool;
use crate::{DVector, Real, INFINITY};
use super::masterprocess::{self, MasterConfig, MasterProcess, MasterResponse};
use crate::master::{self, MasterProblem};
use crate::problem::{EvalResult, FirstOrderProblem, Update, UpdateState};
use crate::terminator::{StandardTerminatable, StandardTerminator, Terminator};
use crate::weighter::{HKWeightable, HKWeighter, Weighter};
|
| ︙ | | | ︙ | |
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
|
impl SolverData {
/// Reset solver data to initial values.
///
/// This means that almost everything is set to +infinity so that
/// a null-step is forced after the first evaluation.
fn init(&mut self, y: DVector) {
self.cur_y = y;
self.cur_val = Real::infinity();
self.nxt_val = Real::infinity();
self.nxt_mod = -Real::infinity();
self.new_cutval = -Real::infinity();
self.expected_progress = Real::infinity();
self.sgnorm = Real::infinity();
self.cur_weight = 1.0;
}
}
impl StandardTerminatable for SolverData {
fn center_value(&self) -> Real {
self.cur_val
|
|
|
|
|
|
|
|
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
|
impl SolverData {
/// Reset solver data to initial values.
///
/// This means that almost everything is set to +infinity so that
/// a null-step is forced after the first evaluation.
fn init(&mut self, y: DVector) {
self.cur_y = y;
self.cur_val = INFINITY;
self.nxt_val = INFINITY;
self.nxt_mod = -INFINITY;
self.new_cutval = -INFINITY;
self.expected_progress = INFINITY;
self.sgnorm = INFINITY;
self.cur_weight = 1.0;
}
}
impl StandardTerminatable for SolverData {
fn center_value(&self) -> Real {
self.cur_val
|
| ︙ | | | ︙ | |
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
|
impl IterData {
fn new(num_subproblems: usize, num_variables: usize, max_iter: usize) -> Self {
IterData {
max_iter,
cnt_iter: 0,
cnt_updates: 0,
nxt_ubs: vec![Real::infinity(); num_subproblems],
cnt_remaining_ubs: num_subproblems,
nxt_cutvals: vec![-Real::infinity(); num_subproblems],
cnt_remaining_mins: num_subproblems,
nxt_d: Arc::new(dvec![0.0; num_variables]),
nxt_y: Arc::new(dvec![]),
updated: true,
}
}
}
|
|
|
|
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
|
impl IterData {
fn new(num_subproblems: usize, num_variables: usize, max_iter: usize) -> Self {
IterData {
max_iter,
cnt_iter: 0,
cnt_updates: 0,
nxt_ubs: vec![INFINITY; num_subproblems],
cnt_remaining_ubs: num_subproblems,
nxt_cutvals: vec![-INFINITY; num_subproblems],
cnt_remaining_mins: num_subproblems,
nxt_d: Arc::new(dvec![0.0; num_variables]),
nxt_y: Arc::new(dvec![]),
updated: true,
}
}
}
|
| ︙ | | | ︙ | |
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
|
if self.data.cur_val.is_infinite() {
// This is the first evaluation. We effectively get
// the function value at the current center but
// we do not have a model estimate yet. Hence, we do not know
// a good guess for the weight.
step = Step::Descent;
self.data.cur_val = nxt_ub;
self.data.cur_weight = Real::infinity();
master.set_weight(1.0)?;
itdata.updated = true;
debug!("First Step");
debug!(" cur_val={}", self.data.cur_val);
debug!(" cur_y={}", self.data.cur_y);
|
|
|
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
|
if self.data.cur_val.is_infinite() {
// This is the first evaluation. We effectively get
// the function value at the current center but
// we do not have a model estimate yet. Hence, we do not know
// a good guess for the weight.
step = Step::Descent;
self.data.cur_val = nxt_ub;
self.data.cur_weight = INFINITY;
master.set_weight(1.0)?;
itdata.updated = true;
debug!("First Step");
debug!(" cur_val={}", self.data.cur_val);
debug!(" cur_y={}", self.data.cur_y);
|
| ︙ | | | ︙ | |
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
|
let mut next_y = dvec![];
itdata.nxt_d = Arc::new(master_res.nxt_d);
next_y.add(&self.data.cur_y, &itdata.nxt_d);
itdata.nxt_y = Arc::new(next_y);
// Reset evaluation data.
itdata.nxt_ubs.clear();
itdata.nxt_ubs.resize(self.problem.num_subproblems(), Real::infinity());
itdata.cnt_remaining_ubs = self.problem.num_subproblems();
itdata.nxt_cutvals.clear();
itdata
.nxt_cutvals
.resize(self.problem.num_subproblems(), -Real::infinity());
itdata.cnt_remaining_mins = self.problem.num_subproblems();
// Start evaluation of all subproblems at the new candidate.
let client_tx = self.client_tx.as_ref().ok_or(Error::NotInitialized)?;
for i in 0..self.problem.num_subproblems() {
self.problem
.evaluate(i, itdata.nxt_y.clone(), i, client_tx.clone())
|
|
<
<
|
|
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
|
let mut next_y = dvec![];
itdata.nxt_d = Arc::new(master_res.nxt_d);
next_y.add(&self.data.cur_y, &itdata.nxt_d);
itdata.nxt_y = Arc::new(next_y);
// Reset evaluation data.
itdata.nxt_ubs.clear();
itdata.nxt_ubs.resize(self.problem.num_subproblems(), INFINITY);
itdata.cnt_remaining_ubs = self.problem.num_subproblems();
itdata.nxt_cutvals.clear();
itdata.nxt_cutvals.resize(self.problem.num_subproblems(), -INFINITY);
itdata.cnt_remaining_mins = self.problem.num_subproblems();
// Start evaluation of all subproblems at the new candidate.
let client_tx = self.client_tx.as_ref().ok_or(Error::NotInitialized)?;
for i in 0..self.problem.num_subproblems() {
self.problem
.evaluate(i, itdata.nxt_y.clone(), i, client_tx.clone())
|
| ︙ | | | ︙ | |