RsBundle  Diff

Differences From Artifact [9ddca66ea3]:

  • File src/solver/sync.rs — part of check-in [c2bd793827] at 2022-06-11 16:45:33 on branch solver-state — Add save and restore of current state to master problems and sync solver (user: fifr size: 32502)

To Artifact [a77fadbefc]:

  • File src/solver/sync.rs — part of check-in [fb8a269092] at 2022-06-11 18:12:56 on branch solver-state — Merge trunk (user: fifr size: 32071) [more...]

34
35
36
37
38
39
40
41

42
43
44
45
46
47
48
34
35
36
37
38
39
40

41
42
43
44
45
46
47
48







-
+







use threadpool::ThreadPool;

use crate::{DVector, Minorant, Real};

use super::channels::{
    ChannelResultSender, ChannelUpdateSender, ClientReceiver, ClientSender, EvalResult, Message, Update,
};
use super::masterprocess::{MasterConfig, MasterError, MasterProcess, MasterResponse, Response};
use super::masterprocess::{MasterError, MasterProcess, MasterResponse, Response};
use crate::master::{Builder as MasterBuilder, MasterProblem};
use crate::problem::{FirstOrderProblem, UpdateState};
use crate::terminator::{StandardTerminatable, StandardTerminator, Terminator};
use crate::weighter::{HKWeightable, HKWeighter, Weighter};

/// The default iteration limit.
pub const DEFAULT_ITERATION_LIMIT: usize = 10_000;
491
492
493
494
495
496
497






498
499








500
501
502
503
504
505









506
507
508
509
510
511
512
513
491
492
493
494
495
496
497
498
499
500
501
502
503


504
505
506
507
508
509
510
511
512





513
514
515
516
517
518
519
520
521

522
523
524
525
526
527
528







+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+

-
-
-
-
-
+
+
+
+
+
+
+
+
+
-







        self.cnt_null = 0;
        self.cnt_evals = 0;

        let (tx, rx) = channel();
        self.client_tx = Some(tx.clone());
        self.client_rx = Some(rx);

        let lower_bounds = self.problem.lower_bounds().map(DVector);
        if lower_bounds.as_ref().map(|lb| lb.len() != n).unwrap_or(false) {
            return Err(Error::Dimension {
                what: "lower bounds".to_string(),
            });
        }
        let master_config = self.build_master_config()?;


        let upper_bounds = self.problem.upper_bounds().map(DVector);
        if upper_bounds.as_ref().map(|ub| ub.len() != n).unwrap_or(false) {
            return Err(Error::Dimension {
                what: "upper bounds".to_string(),
            });
        }

        debug!("Start master process");
        self.master_proc = Some(MasterProcess::start(
            self.master.build().map_err(Error::BuildMaster)?,
            master_config,
            tx,
            &mut self.threadpool,

        // Initialize the master problem.
        let mut master = self.master.build().map_err(Error::BuildMaster)?;
        master.set_num_subproblems(m).map_err(Error::BuildMaster)?;
        master
            .set_vars(n, lower_bounds, upper_bounds)
            .map_err(Error::BuildMaster)?;

        self.master_proc = Some(MasterProcess::start(master, tx, &mut self.threadpool));
        ));

        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
                .evaluate(
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
536
537
538
539
540
541
542




































543
544
545
546
547
548
549







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







        debug!("Initialization complete");

        self.start_time = Instant::now();

        Ok(())
    }

    fn build_master_config(&self) -> Result<MasterConfig, P, M> {
        let n = self.problem.num_variables();
        let m = self.problem.num_subproblems();

        let master_config = MasterConfig {
            num_subproblems: m,
            num_vars: n,
            lower_bounds: self.problem.lower_bounds().map(DVector),
            upper_bounds: self.problem.upper_bounds().map(DVector),
        };

        if master_config
            .lower_bounds
            .as_ref()
            .map(|lb| lb.len() != n)
            .unwrap_or(false)
        {
            return Err(Error::Dimension {
                what: "lower bounds".to_string(),
            });
        }

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

        Ok(master_config)
    }

    fn reset_iteration_data(&mut self, max_iter: usize) {
        let num_subproblems = self.problem.num_subproblems();
        let num_variables = self.problem.num_variables();

        self.data.max_iter = max_iter;
        self.data.cnt_iter = 0;
        self.data.cnt_updates = 0;
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
921
922
923
924
925
926
927


928
929
930
931
932
933
934
935
936
937
938
939

940
941
942
943
944
945
946







-
-












-







    M: MasterBuilder<P::Minorant>,
{
    /// Initialize the solver with the given state.
    pub fn set_state(
        &mut self,
        state: SyncSolverState<<M::MasterProblem as MasterProblem<<P as FirstOrderProblem>::Minorant>>::State>,
    ) -> Result<(), P, M> {
        let master_config = self.build_master_config()?;

        self.data = state.data;
        self.cnt_descent = state.cnt_descent;
        self.cnt_null = state.cnt_null;
        self.cnt_evals = state.cnt_evals;

        let (tx, rx) = channel();
        self.client_tx = Some(tx.clone());
        self.client_rx = Some(rx);

        self.master_proc = if let Some(s) = state.master_state {
            Some(MasterProcess::start(
                self.master.build_with_state(s).map_err(Error::BuildMaster)?,
                master_config,
                tx,
                &mut self.threadpool,
            ))
        } else {
            None
        };