ComputationController

Trait ComputationController 

Source
pub trait ComputationController: Clone + UnstableSealed {
    type Abort: Send;

    // Provided methods
    fn checkpoint(&self, _description: Arguments<'_>) -> Result<(), Self::Abort> { ... }
    fn run_computation<F, T>(
        self,
        _description: Arguments<'_>,
        computation: F,
    ) -> T
       where F: FnOnce(Self) -> T { ... }
    fn log(&self, _description: Arguments<'_>) { ... }
    fn join<A, B, RA, RB>(self, oper_a: A, oper_b: B) -> (RA, RB)
       where A: FnOnce(Self) -> RA + Send,
             B: FnOnce(Self) -> RB + Send,
             RA: Send,
             RB: Send { ... }
}
Expand description

Trait for objects that observe and control a potentially long-running computation.

The idea is that this trait defines multiple functions that can be called during an algorithm, and provide certain functionality. This way, each algorithm can decide which functionality is relevant and how it is used.

This is currently unstable-sealed, since I expect significant additional functionality, potentially including

  • Early aborts, timeouts
  • Multithreading
  • Logging

As a user, this trait should currently be used by passing either LogProgress or DontObserve to algorithms.

Also, note that all description parameters passed to computation controller functions are only for logging/debugging purposes only. There is no specified format, nor any stability guarantees on those messages.

§Example

Which features of a ComputationController an algorithm supports is completely up to the algorithm. Elliptic Curve factorization currently supports logging, abortion and multithreading.

let ring = zn_64::Zn::new(8591966237);
// factors 8591966237 while printing progress
let factor = lenstra_ec_factor(ring, LOG_PROGRESS).unwrap_or_else(no_error);
assert!(8591966237 % factor == 0);
// factor it again, but don't print progress
let factor = lenstra_ec_factor(ring, DontObserve).unwrap_or_else(no_error);
assert!(8591966237 % factor == 0);

If the multithreading with rayon is enabled, we can also do

// factors 8591966237 using multiple threads
let factor = lenstra_ec_factor(ring, RunMultithreadedLogProgress).unwrap_or_else(no_error);
assert!(8591966237 % factor == 0);

Required Associated Types§

Provided Methods§

Source

fn checkpoint(&self, _description: Arguments<'_>) -> Result<(), Self::Abort>

Called by algorithms in (more or less) regular time intervals, can provide e.g. early aborts or tracking progress.

Source

fn run_computation<F, T>(self, _description: Arguments<'_>, computation: F) -> T
where F: FnOnce(Self) -> T,

Runs the given closure with a clone of this iterator, possibly adding a log message before and/or after the computation starts/finishes.

I am currently not completely sure what the right behavior is when this function is called multiple times (possibly nested) for clones of the current controller. We should certainly support nesting of computations, but what should happen in multithreaded scenarios, if we have clones of controllers, or multiple different controllers?

Source

fn log(&self, _description: Arguments<'_>)

Source

fn join<A, B, RA, RB>(self, oper_a: A, oper_b: B) -> (RA, RB)
where A: FnOnce(Self) -> RA + Send, B: FnOnce(Self) -> RB + Send, RA: Send, RB: Send,

Inspired by Rayon, and behaves the same as join() there. Concretely, this function runs both closures, possibly in parallel, and returns their results.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§