Struct ParFair

Source
pub struct ParFair<G: RandomAccessGraph, const PRED: bool = false> { /* private fields */ }
Expand description

Fair parallel breadth-first visits.

“Fairness” refers to the fact that the visit is parallelized by dividing the visit queue in chunks of approximately equal size; threads consume the chunks, and visit the associated nodes. Thus, the visiting cost is distributed evenly among the threads, albeit the work done on the enumeration of successors depends on the sum of the outdegrees nodes in a chunk, which might differ significantly between chunks.

There are two version of the visit, which are type aliases to the same common implementation: ParFairNoPred and ParFairPred.

  • ParFairNoPred does not keep track of predecessors; it can be used, for example, to compute distances.
  • ParFairPred keeps track of predecessors; it can be used, for example, to compute a visit tree.

Each type of visit uses incrementally more space:

  • ParFairNoPred uses one bit per node to remember known nodes and a queue of usize representing nodes;
  • ParFairPred uses one bit per node to remember known nodes and a queue of pairs of usize representing nodes and their parents.

If you need predecessors but the cost of the callbacks is not significant you can use a low-memory parallel visit instead.

The visits differ also in the type of events they generate:

With respect to EventNoPred, EventPred provides the predecessor of the current node.

§Examples

Let’s compute the distances from 0. We will be using a SyncSlice from the sync_cell_slice crate to store the parent of each node.

use webgraph_algo::visits::Parallel;
use webgraph_algo::visits::breadth_first::{*, self};
use webgraph_algo::thread_pool;
use webgraph::graphs::vec_graph::VecGraph;
use webgraph::labels::proj::Left;
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering;
use std::ops::ControlFlow::Continue;
use sync_cell_slice::SyncSlice;
use no_break::NoBreak;

let graph = VecGraph::from_arcs([(0, 1), (1, 2), (2, 0), (1, 3)]);
let mut visit = breadth_first::ParFairNoPred::new(&graph);
let mut d = [0_usize; 4];
let mut d_sync = d.as_sync_slice();
visit.par_visit(
    [0],
    |event| {
        // Set distance from 0
        if let EventNoPred::Unknown { node, distance, ..} = event {
            // There will be exactly one set for each node
            unsafe { d_sync[node].set(distance) };
        }
        Continue(())
    },
   &thread_pool![],
).continue_value_no_break();

assert_eq!(d[0], 0);
assert_eq!(d[1], 1);
assert_eq!(d[2], 2);
assert_eq!(d[3], 2);

Implementations§

Source§

impl<G: RandomAccessGraph, const P: bool> ParFair<G, P>

Source

pub fn new(graph: G) -> Self

Creates a fair parallel breadth-first visit.

This constructor uses a default granularity of 128 nodes. Use with_granularity to set a different granularity.

§Arguments
  • graph: the graph to visit.
Source

pub fn with_granularity(graph: G, granularity: Granularity) -> Self

Creates a fair parallel breadth-first visit.

§Arguments
  • graph: the graph to visit.

  • granularity: High granularity reduces overhead, but may lead to decreased performance on graphs with a skewed outdegree distribution. From this parameter, we derive a node granularity.

Trait Implementations§

Source§

impl<G: RandomAccessGraph + Sync> Parallel<EventNoPred> for ParFair<G, false>

Source§

fn par_visit_filtered_with<R: IntoIterator<Item = usize>, T: Clone + Send + Sync, E: Send, C: Fn(&mut T, EventNoPred) -> ControlFlow<E, ()> + Sync, F: Fn(&mut T, FilterArgsNoPred) -> bool + Sync>( &mut self, roots: R, init: T, callback: C, filter: F, thread_pool: &ThreadPool, ) -> ControlFlow<E, ()>

Visits the graph from the specified nodes with an initialization value and a filter function. Read more
Source§

fn reset(&mut self)

Resets the visit status, making it possible to reuse it.
Source§

fn par_visit_filtered<R: IntoIterator<Item = usize>, E: Send, C: Fn(A) -> ControlFlow<E, ()> + Sync, F: Fn(A::FilterArgs) -> bool + Sync>( &mut self, roots: R, callback: C, filter: F, thread_pool: &ThreadPool, ) -> ControlFlow<E, ()>

Visits the graph from the specified nodes with a filter function. Read more
Source§

fn par_visit_with<R: IntoIterator<Item = usize>, T: Clone + Send + Sync, E: Send, C: Fn(&mut T, A) -> ControlFlow<E, ()> + Sync>( &mut self, roots: R, init: T, callback: C, thread_pool: &ThreadPool, ) -> ControlFlow<E, ()>

Visits the graph from the specified nodes with an initialization value. Read more
Source§

fn par_visit<R: IntoIterator<Item = usize>, E: Send, C: Fn(A) -> ControlFlow<E, ()> + Sync>( &mut self, roots: R, callback: C, thread_pool: &ThreadPool, ) -> ControlFlow<E, ()>

Visits the graph from the specified nodes. Read more
Source§

impl<G: RandomAccessGraph + Sync> Parallel<EventPred> for ParFair<G, true>

Source§

fn par_visit_filtered_with<R: IntoIterator<Item = usize>, T: Clone + Send + Sync, E: Send, C: Fn(&mut T, EventPred) -> ControlFlow<E, ()> + Sync, F: Fn(&mut T, <EventPred as Event>::FilterArgs) -> bool + Sync>( &mut self, roots: R, init: T, callback: C, filter: F, thread_pool: &ThreadPool, ) -> ControlFlow<E, ()>

Visits the graph from the specified nodes with an initialization value and a filter function. Read more
Source§

fn reset(&mut self)

Resets the visit status, making it possible to reuse it.
Source§

fn par_visit_filtered<R: IntoIterator<Item = usize>, E: Send, C: Fn(A) -> ControlFlow<E, ()> + Sync, F: Fn(A::FilterArgs) -> bool + Sync>( &mut self, roots: R, callback: C, filter: F, thread_pool: &ThreadPool, ) -> ControlFlow<E, ()>

Visits the graph from the specified nodes with a filter function. Read more
Source§

fn par_visit_with<R: IntoIterator<Item = usize>, T: Clone + Send + Sync, E: Send, C: Fn(&mut T, A) -> ControlFlow<E, ()> + Sync>( &mut self, roots: R, init: T, callback: C, thread_pool: &ThreadPool, ) -> ControlFlow<E, ()>

Visits the graph from the specified nodes with an initialization value. Read more
Source§

fn par_visit<R: IntoIterator<Item = usize>, E: Send, C: Fn(A) -> ControlFlow<E, ()> + Sync>( &mut self, roots: R, callback: C, thread_pool: &ThreadPool, ) -> ControlFlow<E, ()>

Visits the graph from the specified nodes. Read more

Auto Trait Implementations§

§

impl<G, const PRED: bool> Freeze for ParFair<G, PRED>
where G: Freeze,

§

impl<G, const PRED: bool> RefUnwindSafe for ParFair<G, PRED>
where G: RefUnwindSafe,

§

impl<G, const PRED: bool> Send for ParFair<G, PRED>
where G: Send,

§

impl<G, const PRED: bool> Sync for ParFair<G, PRED>
where G: Sync,

§

impl<G, const PRED: bool> Unpin for ParFair<G, PRED>
where G: Unpin,

§

impl<G, const PRED: bool> UnwindSafe for ParFair<G, PRED>
where G: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CastableFrom<T> for T

Source§

fn cast_from(value: T) -> T

Call Self as W
Source§

impl<T> CastableFrom<T> for T

Source§

fn cast_from(value: T) -> T

Call Self as W
Source§

impl<T, U> CastableInto<U> for T
where U: CastableFrom<T>,

Source§

fn cast(self) -> U

Call W::cast_from(self)
Source§

impl<T, U> CastableInto<U> for T
where U: CastableFrom<T>,

Source§

fn cast(self) -> U

Call W::cast_from(self)
Source§

impl<T> DowncastableFrom<T> for T

Source§

fn downcast_from(value: T) -> T

Truncate the current UnsignedInt to a possibly smaller size
Source§

impl<T> DowncastableFrom<T> for T

Source§

fn downcast_from(value: T) -> T

Truncate the current UnsignedInt to a possibly smaller size
Source§

impl<T, U> DowncastableInto<U> for T
where U: DowncastableFrom<T>,

Source§

fn downcast(self) -> U

Call W::downcast_from(self)
Source§

impl<T, U> DowncastableInto<U> for T
where U: DowncastableFrom<T>,

Source§

fn downcast(self) -> U

Call W::downcast_from(self)
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Splat<T> for T

Source§

fn splat(value: T) -> T

Source§

impl<T> Splat<T> for T

Source§

fn splat(value: T) -> T

Source§

impl<T> To<T> for T

Source§

fn to(self) -> T

Source§

impl<T> To<T> for T

Source§

fn to(self) -> T

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> UpcastableFrom<T> for T

Source§

fn upcast_from(value: T) -> T

Extend the current UnsignedInt to a possibly bigger size.
Source§

impl<T> UpcastableFrom<T> for T

Source§

fn upcast_from(value: T) -> T

Extend the current UnsignedInt to a possibly bigger size.
Source§

impl<T, U> UpcastableInto<U> for T
where U: UpcastableFrom<T>,

Source§

fn upcast(self) -> U

Call W::upcast_from(self)
Source§

impl<T, U> UpcastableInto<U> for T
where U: UpcastableFrom<T>,

Source§

fn upcast(self) -> U

Call W::upcast_from(self)
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V