|
6 | 6 | rank = comm.Get_rank()
|
7 | 7 | nprocs = comm.Get_size()
|
8 | 8 |
|
9 |
| -N = 500 |
10 |
| -M = 500 |
| 9 | +N = 400 |
| 10 | +M = 600 |
| 11 | + |
| 12 | +#This example exchanges data among four rectangular domains with halos. |
| 13 | +#Most real codes use squares, but we want to illustrate how to use different |
| 14 | +#dimensions. |
11 | 15 |
|
12 | 16 | #Divide up the processes. Either we require a perfect square, or we
|
13 | 17 | #must specify how to distribute by row/column. In a realistic program,
|
14 | 18 | #the process distribution (either the total, for a perfect square, or
|
15 | 19 | #the rows/columns) would be read in and we would need to check that the number
|
16 | 20 | #of processes requested is consistent with the decomposition.
|
17 | 21 |
|
18 |
| -nproc_rows=5 |
19 |
| -nproc_cols=5 |
| 22 | +nproc_rows=2 |
| 23 | +nproc_cols=3 |
20 | 24 |
|
21 | 25 | if nproc_rows*nproc_cols != nprocs:
|
22 | 26 | print("Number of rows times columns does not equal nprocs")
|
23 | 27 | sys.exit()
|
24 | 28 |
|
25 | 29 | #Strong scaling
|
26 |
| -if N%nprocs==0 and M%nprocs==0: |
| 30 | +if N%nproc_rows==0 and M%nproc_cols==0: |
27 | 31 | nrl = N//nproc_rows
|
28 | 32 | ncl = M//nproc_cols
|
29 | 33 | else:
|
30 | 34 | print("Number of ranks should divide the number of rows evenly.")
|
31 | 35 | sys.exit()
|
32 | 36 |
|
33 |
| -#Weak scaling |
34 |
| -#nrl = N |
35 |
| -#ncl = M |
36 |
| - |
37 | 37 | w = np.zeros((nrl+2, ncl+2), dtype=np.double)
|
38 | 38 |
|
39 | 39 | #Set up the topology assuming processes numbered left to right by row
|
40 | 40 |
|
41 |
| -my_row=rank%nproc_rows |
42 |
| -my_col=rank%nproc_cols |
| 41 | +print("Layout ",nproc_rows,nproc_cols) |
| 42 | + |
| 43 | +my_row=rank%nproc_cols |
| 44 | +my_col=rank%nproc_rows |
| 45 | + |
| 46 | +print("Topology ",rank,my_row,my_col) |
43 | 47 |
|
44 | 48 | #Set up boundary conditions
|
45 | 49 | if my_row == 0:
|
|
54 | 58 | if my_col == nproc_cols-1:
|
55 | 59 | w[:,ncl+1] = 100. # right
|
56 | 60 |
|
57 |
| -#Arbitarary value for interior that may speed up convergence somewhat. |
| 61 | +#Arbitrary value for interior that may speed up convergence somewhat. |
58 | 62 | #Be sure not to overwrite boundaries.
|
59 | 63 | w[1:nrl+1,1:ncl+1] = 50.
|
60 | 64 |
|
61 | 65 | # setting up the up and down rank for each process
|
62 | 66 | if my_row == 0 :
|
63 | 67 | up = MPI.PROC_NULL
|
64 | 68 | else :
|
65 |
| - up = rank - ncols |
| 69 | + up = rank - nproc_cols |
66 | 70 |
|
67 | 71 | if my_row == nprocs - 1 :
|
68 | 72 | down = MPI.PROC_NULL
|
69 | 73 | else :
|
70 |
| - down = rank + ncols |
| 74 | + down = rank + nproc_cols |
71 | 75 |
|
72 | 76 | if my_col == 0 :
|
73 | 77 | left = MPI.PROC_NULL
|
74 | 78 | else:
|
75 | 79 | left = rank-1
|
76 | 80 |
|
77 |
| -if my_col == ncols-1: |
| 81 | +if my_col == ncl-1: |
78 | 82 | right = MPI.PROC_NULL
|
79 | 83 | else:
|
80 | 84 | right = rank+1
|
81 | 85 |
|
| 86 | +print("Upsie downsie ",rank,my_row,my_col,up,down) |
| 87 | + |
82 | 88 | # set up MPI vector type for column
|
83 |
| -column=MPI.DOUBLE.Create_vector( |
| 89 | +column=MPI.DOUBLE.Create_vector(nrl,1,ncl) |
| 90 | +column.Commit() |
84 | 91 |
|
85 | 92 | tag=0
|
86 | 93 |
|
|
90 | 97 | comm.Sendrecv([w[nrl,1:ncl+1],MPI.DOUBLE], down, tag, [w[0,1:ncl+1],MPI.DOUBLE], up, tag)
|
91 | 98 |
|
92 | 99 | # sending right and left.
|
| 100 | +comm.Sendrecv((w[0,ncl+1:ncl+2],1,column), right, tag, (w[0:,1],MPI.DOUBLE), left, tag) |
| 101 | + |
| 102 | +comm.Sendrecv((w[0,0:1],1,column), left, tag, (w[0:,ncl],1,MPI.DOUBLE), left, tag) |
93 | 103 |
|
94 | 104 | # Spot-check result
|
95 | 105 | for n in range(nprocs):
|
|
0 commit comments