RsBundle  Diff

Differences From Artifact [cb2c7849ad]:

  • File src/parallel/solver.rs — part of check-in [04cb8ebb99] at 2019-07-21 20:52:30 on branch async — parallel::solver: fix ref in doc of `init` (user: fifr size: 20104)

To Artifact [7a89c2116c]:

  • File src/parallel/solver.rs — part of check-in [5ee9fe59e5] at 2019-07-22 08:52:58 on branch master-builder — Introduce master problem builder (user: fifr size: 20732)

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
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







+
-
+







+
+
-
+






+
+







use std::time::Instant;
use threadpool::ThreadPool;

use crate::{DVector, Real};

use super::masterprocess::{MasterConfig, MasterProcess};
use super::problem::{EvalResult, FirstOrderProblem};
use crate::master::{boxed, cpx};
use crate::master::{BoxedMasterProblem, CplexMaster, MasterProblem as MP};
use crate::master::{BoxedMasterProblem, Builder, MasterProblem as MP};
use crate::solver::{SolverParams, Step};
use crate::terminator::{StandardTerminatable, StandardTerminator, Terminator};
use crate::weighter::{HKWeightable, HKWeighter, Weighter};

/// The default iteration limit.
pub const DEFAULT_ITERATION_LIMIT: usize = 10_000;

type MasterBuilder = boxed::Builder<cpx::Builder>;

type MasterProblem = BoxedMasterProblem<CplexMaster>;
type MasterProblem = BoxedMasterProblem<cpx::CplexMaster>;

type MasterProblemError = <MasterProblem as MP>::Err;

/// Error raised by the parallel bundle [`Solver`].
#[derive(Debug)]
pub enum Error<E> {
    /// An error raised when creating a new master problem solver.
    BuildMaster(Box<dyn std::error::Error>),
    /// An error raised by the master problem process.
    Master(MasterProblemError),
    /// The iteration limit has been reached.
    IterationLimit { limit: usize },
    /// An error raised by a subproblem evaluation.
    Evaluation(E),
    /// The dimension of some data is wrong.
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
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







+

















+







impl<E> std::fmt::Display for Error<E>
where
    E: std::fmt::Display,
{
    fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::result::Result<(), std::fmt::Error> {
        use Error::*;
        match self {
            BuildMaster(err) => writeln!(fmt, "Cannot create master problem solver: {}", err),
            Master(err) => writeln!(fmt, "Error in master problem: {}", err),
            IterationLimit { limit } => writeln!(fmt, "The iteration limit has been reached: {}", limit),
            Evaluation(err) => writeln!(fmt, "Error in subproblem evaluation: {}", err),
            Dimension(what) => writeln!(fmt, "Wrong dimension for {}", what),
            Process(err) => writeln!(fmt, "Error in subprocess: {}", err),
            NotInitialized => writeln!(fmt, "The solver must be initialized (called Solver::init()?)"),
        }
    }
}

impl<E> std::error::Error for Error<E>
where
    E: std::error::Error + 'static,
{
    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
        use Error::*;
        match self {
            BuildMaster(err) => Some(err.as_ref()),
            Master(err) => Some(err),
            Evaluation(err) => Some(err),
            Process(err) => Some(err.as_ref()),
            _ => None,
        }
    }
}
180
181
182
183
184
185
186



187
188
189
190
191
192
193
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203







+
+
+







    pub threadpool: ThreadPool,

    /// The first order problem.
    problem: P,

    /// The algorithm data.
    data: SolverData,

    /// The master problem builder.
    master_builder: MasterBuilder,

    /// The master problem process.
    master: Option<MasterProcess<P, MasterProblem>>,

    /// The channel to receive the evaluation results from subproblems.
    client_tx: Option<ClientSender<P>>,

231
232
233
234
235
236
237

238
239
240
241
242
243
244
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255







+







                nxt_mod: 0.0,
                new_cutval: 0.0,
                sgnorm: 0.0,
                cur_weight: 1.0,
            },

            threadpool: ThreadPool::with_name("Parallel bundle solver".to_string(), num_cpus::get()),
            master_builder: MasterBuilder::default(),
            master: None,
            client_tx: None,
            client_rx: None,

            cnt_descent: 0,
            cnt_null: 0,
            cnt_evals: 0,
310
311
312
313
314
315
316
317







318
319
320
321
322
323
324
321
322
323
324
325
326
327

328
329
330
331
332
333
334
335
336
337
338
339
340
341







-
+
+
+
+
+
+
+







            .map(|ub| ub.len() != n)
            .unwrap_or(false)
        {
            return Err(Error::Dimension("upper bounds".to_string()));
        }

        debug!("Start master process");
        self.master = Some(MasterProcess::start(master_config, &mut self.threadpool));
        self.master = Some(MasterProcess::start(
            self.master_builder
                .build()
                .map_err(|err| Error::BuildMaster(err.into()))?,
            master_config,
            &mut self.threadpool,
        ));
        let master = self.master.as_mut().unwrap();

        debug!("Initial problem evaluation");
        // We need an initial evaluation of all oracles for the first center.
        let y = Arc::new(self.data.cur_y.clone());
        for i in 0..m {
            self.problem