-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathmulti_process_multiplier.py
188 lines (150 loc) · 4.97 KB
/
multi_process_multiplier.py
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
from mpi4py import MPI
from random import randint
import time
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
workers = comm.Get_size() - 1
mtrx1 = []
mtrx2 = []
mtrx3 = []
N = 500
def init_matrix():
"""
Initialize matrix from here, we do initialize three matrix from here
1. mtrx1 - input matrix
2. mtrx2 - input matrix
3. mtrx3 - output matrix
"""
global mtrx1
mtrx1 = [[randint(0, 9) for i in range(N)] for j in range(N)]
global mtrx2
mtrx2 = [[randint(0, 9) for i in range(N)] for j in range(N)]
def multiply_matrix(X, Y):
"""
Generate new matrix by multiplying incoming matrix data.
This function will be called by each and every slave with their matrix
data. For an example
X = [
[1, 2, 3, 4],
[3, 2, 3, 7],
]
Y = [
[1, 2, 3],
[5, 6, 7],
[2, 2, 7],
[5, 6, 9],
]
Z = [
[(1*1 + 2*5 + 3*2 + 4*5), (1*2 + 2*6 + 3*2 + 4*6), --, --],
[(3*1 + 2*5 + 3*2 + 7*5), (3*2 + 2*6 + 3*2 + 7*6), --, --]
]
Args:
X: rows of mtrx1
Y: whole mtrx2
Returns:
Z: calculated matrix part
"""
Z = [[sum(a * b for a, b in zip(X_row, Y_col)) for Y_col in zip(*Y)]
for X_row in X]
return Z
def distribute_matrix_data():
"""
Distribute rows of first matrix and whole second matrix to salves, this
done via master node. Then salves calculate a sub matrix by multiplying
incoming matrix and send result back to master
"""
def split_matrix(seq, p):
"""
Split matrix into small parts according to the no of workers. These
parts will be send to slaves by master node
"""
rows = []
n = len(seq) / p
r = len(seq) % p
b, e = 0, n + min(1, r)
for i in range(p):
rows.append(seq[b:e])
r = max(0, r - 1)
b, e = e, e + n + min(1, r)
return rows
rows = split_matrix(mtrx1, workers)
pid = 1
for row in rows:
comm.send(row, dest=pid, tag=1)
comm.send(mtrx2, dest=pid, tag=2)
pid = pid + 1
def assemble_matrix_data():
"""
Assemble returning values form salves and generate final matrix. Slaves
calculate single rows of final matrix
"""
global mtrx3
pid = 1
for n in range(workers):
row = comm.recv(source=pid, tag=pid)
mtrx3 = mtrx3 + row
pid = pid + 1
def master_operation():
"""
Do operation of master node, we have to do following this from here
1. distribute matrix data to slaves
2. assemble salves returning values and generate final matrix
"""
distribute_matrix_data()
assemble_matrix_data()
def slave_operation():
"""
Do operation of slave nodes, we have to do
1. Gather the data sending from master
2. Calculate the single fow of final matrix
3. Send the calculated row back to master
"""
# receive data from master node
x = comm.recv(source=0, tag=1)
y = comm.recv(source=0, tag=2)
# multiply the received matrix and send the result back to master
z = multiply_matrix(x, y)
comm.send(z, dest=0, tag=rank)
if __name__ == '__main__':
"""
Main method here, we have to do
1. initialize matrix
2. Master/Salve operations
"""
if rank == 0:
init_matrix()
# start time
t1 = time.time()
print('--------------------------------------------------------------')
print('Start time', t1)
print('--------------------------------------------------------------')
print('\n')
master_operation()
# end time
t2 = time.time()
print('--------------------------------------------------------------')
print mtrx1
print('--------------------------------------------------------------')
print('\n')
print('--------------------------------------------------------------')
print mtrx2
print('--------------------------------------------------------------')
print('\n')
print('--------------------------------------------------------------')
print mtrx3
print('--------------------------------------------------------------')
print('\n')
print('--------------------------------------------------------------')
print('Start time', t1)
print('--------------------------------------------------------------')
print('\n')
print('--------------------------------------------------------------')
print('End time', t1)
print('--------------------------------------------------------------')
print('\n')
print('--------------------------------------------------------------')
print('Time taken in seconds', int(t2 - t1))
print('--------------------------------------------------------------')
print('\n')
else:
slave_operation()