File: ex-2.32.py

package info (click to toggle)
mpi4py 4.0.3-4
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 4,196 kB
  • sloc: python: 32,170; ansic: 13,449; makefile: 602; sh: 314; f90: 178; cpp: 148
file content (94 lines) | stat: -rw-r--r-- 2,305 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# Jacobi computation, using persistent requests

from mpi4py import MPI
try:
    import numpy
except ImportError:
    raise SystemExit


n = 5 * MPI.COMM_WORLD.Get_size()

# compute number of processes and myrank
p = MPI.COMM_WORLD.Get_size()
myrank = MPI.COMM_WORLD.Get_rank()

# compute size of local block
m = n//p
if myrank < (n - p * m):
    m = m + 1

#compute neighbors
if myrank == 0:
    left = MPI.PROC_NULL
else:
    left = myrank - 1
if myrank == p - 1:
    right = MPI.PROC_NULL
else:
    right = myrank + 1

# allocate local arrays
A = numpy.empty((n+2, m+2), dtype=float, order='f')
B = numpy.empty((n, m), dtype=float, order='f')

A.fill(1)
A[0, :] = A[-1, :] = 0
A[:, 0] = A[:, -1] = 0

# create persistent requests
tag = 0
sreq1 = MPI.COMM_WORLD.Send_init((B[:,  0], MPI.DOUBLE), left,  tag)
sreq2 = MPI.COMM_WORLD.Send_init((B[:, -1], MPI.DOUBLE), right, tag)
rreq1 = MPI.COMM_WORLD.Recv_init((A[:,  0], MPI.DOUBLE), left,  tag)
rreq2 = MPI.COMM_WORLD.Recv_init((A[:, -1], MPI.DOUBLE), right, tag)
reqlist = [sreq1, sreq2, rreq1, rreq2]

for req in reqlist:
    assert req != MPI.REQUEST_NULL

# main loop
converged = False
while not converged:
    # compute boundary columns
    N, S = A[ :-2, 1], A[2:,   1]
    E, W = A[1:-1, 0], A[1:-1, 2]
    C = B[:, 0]
    numpy.add(N, S, C)
    numpy.add(C, E, C)
    numpy.add(C, W, C)
    C *= 0.25
    N, S = A[ :-2, -2], A[2:,   -2]
    E, W = A[1:-1, -3], A[1:-1, -1]
    C = B[:, -1]
    numpy.add(N, S, C)
    numpy.add(C, E, C)
    numpy.add(C, W, C)
    C *= 0.25
    # start communication
    #MPI.Prequest.Startall(reqlist)
    for r in reqlist:
        r.Start()
    # compute interior
    N, S = A[ :-2, 2:-2], A[2,    2:-2]
    E, W = A[1:-1, 2:-2], A[1:-1, 2:-2]
    C = B[:, 1:-1]
    numpy.add(N, S, C)
    numpy.add(E, C, C)
    numpy.add(W, C, C)
    C *= 0.25
    A[1:-1, 1:-1] = B
    # complete communication
    MPI.Prequest.Waitall(reqlist)
    # convergence
    myconv = numpy.allclose(B, 0)
    loc_conv = numpy.asarray(myconv, dtype='i')
    glb_conv = numpy.asarray(0, dtype='i')
    MPI.COMM_WORLD.Allreduce([loc_conv, MPI.INT],
                             [glb_conv, MPI.INT],
                             op=MPI.LAND)
    converged = bool(glb_conv)

# free persistent requests
for req in reqlist:
    req.Free()