Exemplo n.º 1
0
def scalar_product_test2(n, p):
    comm = PSim(p)
    a = b = None
    if comm.rank == 0:
        a = [random.random() for i in range(n)]
        b = [random.random() for i in range(n)]
    a = comm.one2all_scatter(0, a)
    b = comm.one2all_scatter(0, b)

    scalar = sum(a[i] * b[i] for i in range(len(a)))

    scalar = comm.all2one_reduce(0, scalar)
    if comm.rank == 0:
        print(scalar)
Exemplo n.º 2
0
def scalar_product_test2(n,p):
    import random
    from psim import PSim
    comm = PSim(p)
    a = b = None
    if comm.rank==0:
        a = [random.random() for i in range(n)]
        b = [random.random() for i in range(n)]
    a = comm.one2all_scatter(0,a)
    b = comm.one2all_scatter(0,b)

    scalar = sum(a[i]*b[i] for i in range(len(a)))

    scalar = comm.all2one_reduce(0,scalar)
    if comm.rank == 0:
        print scalar
Exemplo n.º 3
0
def bb(adjacency, p=1):
    n = len(adjacency)
    comm = PSim(p)
    Q = []
    path = [0]
    Q.append(Vertex(path))
    bound = float("inf')
    optimal = None
    local_vertices = comm.one2all_scatter(0, range(n))
    while True:
        if comm.rank == 0:
            vertex = Q.pop() if Q else None
        else:
            vertex = None
        vertex = comm.one2all_broadcast(0, vertex)
        if vertex is None:
            break
        P = []
        for k in local_vertices:
            if not k in vertex.path:
                new_path = vertex.path+[k]
                new_path_length = weight(new_path, adjacency)
                if new_path_length<bound:
                    if len(new_path) == n:
                        new_path.append(new_path[0])
                        new_path_length = weight(new_path, adjacency)
                        if new_path_length<bound:
                            bound = new_path_length  # bcast
                            optimal = new_path       # bcast
                    else:
                        new_vertex = Vertex(new_path)
                        P.append(new_vertex)  # fix this
                print(new_path, new_path_length)
        x = (bound, optimal)
        x = comm.all2all_reduce(x, lambda a, b: min(a, b))
        (bound, optimal) = x

        P = comm.all2one_collect(0, P)
        if comm.rank == 0:
            for item in P:
                Q+=item
    return optimal, bound
Exemplo n.º 4
0
def dijkstra_p(g, source, p):
    """
    PYsim parallel implementation of dijkstra's algorithm
    Result: One source shourtest paths to all nodes
    Implementation parallelizes finding minimums and 
    updating the results (inner loop is parallelized)
    Uses the method of collecting of intermediate minimums and 
    broadcasting of newly found path to all processes
    """
    # Initialize communicator
    comm = PSim(p)
    myRank = comm.rank
    chunkSize = len(g) / p

    # Scatter the graph by partitioning it one dimensionally,
    # along with known distances to source, and remaining node information
    myGraphChunk = comm.one2all_scatter(0, g)
    localResultView = comm.one2all_scatter(0, g[source])
    localRemainView = comm.one2all_scatter(0, g[source])

    # Each process will iterate q times, where q is number of nodes in graph
    for q in range(len(g)):
        # Get shortest path to locally un-visited nodes
        lowestLocalDist = min(localRemainView)
        lowestLocalDistIdx = localRemainView.index(lowestLocalDist)

        # Collect the lowest distances and node indexes from all processes
        gatheredCandidatesDist = comm.all2one_collect(0, lowestLocalDist)
        gatheredCandidatesIdxs = comm.all2one_collect(0, lowestLocalDistIdx + myRank * chunkSize)

        processWithLowestDist = -1
        addedNodeIdx = -1
        lowestOverallDistance = -1

        # One 'main' process finds the global minimum
        if myRank == 0:
            lowestOverallDistance = min(gatheredCandidatesDist)
            processWithLowestDist = gatheredCandidatesDist.index(lowestOverallDistance)
            addedNodeIdx = gatheredCandidatesIdxs[processWithLowestDist]

        # 'Main' process broadcasts the finding to all processes
        receivedBroadcast = comm.one2all_broadcast(0, (processWithLowestDist, addedNodeIdx, lowestOverallDistance))

        # If this process is responsible for the newly found shortest path,
        # then mark this node as visited.
        if myRank == receivedBroadcast[0]:
            indexToUpdate = receivedBroadcast[1] - myRank * chunkSize
            localRemainView[indexToUpdate] = ""

        # Each process loop over all connections to this last visited node
        # that they have the visibility to.
        for iter in range(len(localResultView)):
            potentialNewDistance = myGraphChunk[iter][receivedBroadcast[1]] + receivedBroadcast[2]
            # If the distances through this node are less than what we know
            if potentialNewDistance < localResultView[iter]:
                # Update the local portion of the result list and
                # remaining nodes list
                localResultView[iter] = potentialNewDistance
                localRemainView[iter] = potentialNewDistance

    # Reduce the final result to a single list and return it
    reassembled = comm.all2one_reduce(0, localResultView)
    if myRank == 0:
        return reassembled
    else:
        return []
Exemplo n.º 5
0
def dijkstra_p(g, source, p):
    """
    PYsim parallel implementation of dijkstra's algorithm
    Result: One source shourtest paths to all nodes
    Implementation parallelizes finding minimums and 
    updating the results (inner loop is parallelized)
    Uses the method of collecting of intermediate minimums and 
    broadcasting of newly found path to all processes
    """
    # Initialize communicator
    comm = PSim(p)
    myRank = comm.rank
    chunkSize = len(g) / p

    # Scatter the graph by partitioning it one dimensionally,
    # along with known distances to source, and remaining node information
    myGraphChunk = comm.one2all_scatter(0, g)
    localResultView = comm.one2all_scatter(0, g[source])
    localRemainView = comm.one2all_scatter(0, g[source])

    # Each process will iterate q times, where q is number of nodes in graph
    for q in range(len(g)):
        # Get shortest path to locally un-visited nodes
        lowestLocalDist = min(localRemainView)
        lowestLocalDistIdx = localRemainView.index(lowestLocalDist)

        # Collect the lowest distances and node indexes from all processes
        gatheredCandidatesDist = comm.all2one_collect(0, lowestLocalDist)
        gatheredCandidatesIdxs = comm.all2one_collect(
            0, lowestLocalDistIdx + myRank * chunkSize)

        processWithLowestDist = -1
        addedNodeIdx = -1
        lowestOverallDistance = -1

        # One 'main' process finds the global minimum
        if myRank == 0:
            lowestOverallDistance = min(gatheredCandidatesDist)
            processWithLowestDist = gatheredCandidatesDist.index(
                lowestOverallDistance)
            addedNodeIdx = gatheredCandidatesIdxs[processWithLowestDist]

        # 'Main' process broadcasts the finding to all processes
        receivedBroadcast = \
            comm.one2all_broadcast(0,\
            (processWithLowestDist,addedNodeIdx,lowestOverallDistance,))

        # If this process is responsible for the newly found shortest path,
        # then mark this node as visited.
        if myRank == receivedBroadcast[0]:
            indexToUpdate = receivedBroadcast[1] - myRank * chunkSize
            localRemainView[indexToUpdate] = ''

        # Each process loop over all connections to this last visited node
        # that they have the visibility to.
        for iter in range(len(localResultView)):
            potentialNewDistance = \
                    myGraphChunk[iter][receivedBroadcast[1]]+receivedBroadcast[2]
            # If the distances through this node are less than what we know
            if potentialNewDistance < localResultView[iter]:
                # Update the local portion of the result list and
                # remaining nodes list
                localResultView[iter] = potentialNewDistance
                localRemainView[iter] = potentialNewDistance

    # Reduce the final result to a single list and return it
    reassembled = comm.all2one_reduce(0, localResultView)
    if myRank == 0:
        return reassembled
    else:
        return []