ParallelGraph

public protocol ParallelGraph : PropertyGraph

A graph that supports vertex-parallel graph algorithms.

Graph structures are often parallelizable. One common way to parallelize is to parallelize by vertex. In this “think-like-a-vertex”, computation is organized into a series of steps, where each vertex executes executes on “local” information, such as vertex-specific properties, as well as the set of edges leaving the vertex. In order to compute useful properties of the graph, a mailbox abstraction is provided that allows a vertex to receive messages from a previous algorithm step, and to send messages to arbitrary other verticies that will be received in the subsequent step.

This abstraction is inspired by:

Pregel: A System for Large-Scale Graph Processing (2010) Grzegorz Malewicz, Matthew H. Austern, Aart J. C. Bik, James C. Dehnert, Ilan Horn, Naty Leiser, and Grzegorz Czajkowski

See also

MailboxesProtocol

See also

MailboxProtocol
  • The parallel representation of Self.

    Most graphs have value semantics. This is at odds with data-parallel processing (where non-overlapping mutations occur across multiple threads). In order to support value semantics and parallel processing, we define an associated type ParallelProjection, which is a representation of self with mutation semantics compatible with data-parallel operations.

    Declaration

    Swift

    associatedtype ParallelProjection: GraphProtocol where
      ParallelProjection.VertexId == VertexId,
      ParallelProjection.EdgeId == EdgeId
  • The context that is passed to the vertex-parallel functions during execution.

    Declaration

    Swift

    typealias Context<Mailbox: MailboxProtocol, GlobalState: MergeableMessage> =
      ParallelGraphAlgorithmContext<ParallelProjection, Mailbox.Message, GlobalState, Mailbox>
    where Mailbox.Graph == ParallelProjection
  • The type of functions that can be executed in vertex-parallel fashion across the graph.

    Declaration

    Swift

    typealias VertexParallelFunction<Mailbox: MailboxProtocol, GlobalState: MergeableMessage> =
      (inout Context<Mailbox, GlobalState>, inout Vertex) throws -> GlobalState?
    where Mailbox.Graph == ParallelProjection
  • Runs fn across each vertex delivering messages in mailboxes, making globalState available to each vertex; returns the merged outputs from each vertex.

    While read-only edge property maps can be used as part of the computation, all use of vertex property maps are prohibited, as use could cause race conditions and violations of Swift’s law of exlusivity.

    Declaration

    Swift

    mutating func step<
      Mailboxes: MailboxesProtocol,
      GlobalState: MergeableMessage & DefaultInitializable
    >(
      mailboxes: inout Mailboxes,
      globalState: GlobalState,
      _ fn: VertexParallelFunction<Mailboxes.Mailbox, GlobalState>
    ) rethrows -> GlobalState where Mailboxes.Mailbox.Graph == ParallelProjection

Parallel Graph Algorithms

Available where Self: IncidenceGraph, Self.Vertex: LabeledVertex

Available where Vertex: ReachableVertex, Self: IncidenceGraph

Available where Self: IncidenceGraph, Vertex: DistanceVertex, Vertex.VertexId == VertexId

  • Executes breadth first search in parallel.

    Note: distances are not kept track of during BFS; at the conclusion of this algorithm, the vertex.distance will be .zero if it’s reachable, and effectivelyInfinite otherwise.

    Declaration

    Swift

    public mutating func computeBFS<
      Distance: FloatingPoint,
      Mailboxes: MailboxesProtocol
    >(
      startingAt startVertex: VertexId,
      using mailboxes: inout Mailboxes
    ) -> Int
    where
      Mailboxes.Mailbox.Graph == ParallelProjection,
      ParallelProjection: IncidenceGraph,
      Vertex.Distance == Distance,
      Mailboxes.Mailbox.Message == DistanceSearchMessage<VertexId, Distance>

    Parameters

    startVertex

    The verticies to begin search at.

    Return Value

    the number of steps taken to compute the closure (aka longest path length).

  • Executes breadth first search in parallel.

    Note: distances are not kept track of during BFS; at the conclusion of this algorithm, the vertex.distance will be .zero if it’s reachable, and effectivelyInfinite otherwise.

    Declaration

    Swift

    public mutating func computeBFS<
      Distance: FixedWidthInteger,
      Mailboxes: MailboxesProtocol
    >(
      startingAt startVertex: VertexId,
      using mailboxes: inout Mailboxes
    ) -> Int
    where
      Mailboxes.Mailbox.Graph == ParallelProjection,
      ParallelProjection: IncidenceGraph,
      Vertex.Distance == Distance,
      Mailboxes.Mailbox.Message == DistanceSearchMessage<VertexId, Distance>

    Parameters

    startVertex

    The verticies to begin search at.

    Return Value

    the number of steps taken to compute the closure (aka longest path length).

  • Executes breadth first search in parallel.

    Note: distances are not kept track of during BFS; at the conclusion of this algorithm, the vertex.distance will be .zero if it’s reachable, and effectivelyInfinite otherwise.

    Declaration

    Swift

    public mutating func computeBFS<
      StartCollection: Collection,
      Distance: AdditiveArithmetic & Comparable,
      Mailboxes: MailboxesProtocol
    >(
      startingAt startVerticies: StartCollection,
      effectivelyInfinite: Distance,
      using mailboxes: inout Mailboxes
    ) -> Int
    where
      Mailboxes.Mailbox.Graph == ParallelProjection,
      ParallelProjection: IncidenceGraph,
      Vertex.Distance == Distance,
      Mailboxes.Mailbox.Message == DistanceSearchMessage<VertexId, Distance>,
      StartCollection.Element == VertexId

    Parameters

    startVerticies

    The verticies to begin search at.

    Return Value

    the number of steps taken to compute the transitive closure.

  • Computes the shortest paths from startVertex.

    A stopVertex can be used to stop the algorithm early once the shortest path has been computed between startVertex and stopVertex.

    Note: this algorithm correctly handles negative weight edges so long as a stopVertex is not specified. Note that negative cycles imply a non-finite shortest path, and thus result in unspecified behavior.

    Declaration

    Swift

    public mutating func computeShortestPaths<
      Distance: Comparable & AdditiveArithmetic,
      Mailboxes: MailboxesProtocol,
      DistanceMap: ParallelCapablePropertyMap
    >(
      startingAt startVertex: VertexId,
      stoppingAt stopVertex: VertexId? = nil,
      distances: DistanceMap,
      effectivelyInfinite: Distance,
      mailboxes: inout Mailboxes,
      maximumSteps: Int? = nil
    ) -> Int
    where
      Mailboxes.Mailbox.Graph == ParallelProjection,
      ParallelProjection: IncidenceGraph,
      Mailboxes.Mailbox.Message == DistanceSearchMessage<VertexId, Distance>,
      DistanceMap.Graph == Self,
      DistanceMap.Key == EdgeId,
      DistanceMap.Value == Distance,
      Vertex.Distance == Distance

    Parameters

    startVertex

    The vertex to begin search at.

    mailboxes

    The communication primitive to use.

    stopVertex

    If supplied, once the shortest path from startVertex to stopVertex has been determined, searching will stop.

    Return Value

    the number of steps taken to compute the closure (aka longest path length).