-
Notifications
You must be signed in to change notification settings - Fork 0
/
odd_even_sort.py
134 lines (105 loc) · 2.4 KB
/
odd_even_sort.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
from numpy import *
import sys
'''
# Sequential Odd Even Sort
def swap(i,j):
temp = arr[i]
arr[i] = arr[j]
arr[j] = temp
arr = random.randint(0,2000,2000)
# print arr
start = time.time()
for phase in range(len(arr)):
# even phase
if phase%2 == 0 :
for i in range(1,len(arr),2):
if arr[i] < arr[i-1]:
swap(i,i-1)
else:
for i in range(1,len(arr)-1,2):
if arr[i] > arr[i+1]:
swap(i,i+1)
time_taken = time.time()-start
print "Sorted array : " + str(arr)
print "Time taken :"+ str(time_taken)
'''
# Parallel Odd Even Sort
from mpi4py import MPI
comm = MPI.COMM_WORLD
size = comm.Get_size()
rank = comm.Get_rank()
def merge(a,b):
c = zeros(len(a)+len(b),dtype=int64)
i=j=k=0
# print a[i],b[j]
while i<len(a) and j<len(b):
if a[i]<=b[j]:
c[k] = a[i]
i+=1
else:
c[k] = b[j]
j+=1
k+=1
while i<len(a):
c[k] = a[i]
i+=1
k+=1
while j<len(b):
c[k] = b[j]
j+=1
k+=1
return c
def get_partner(phase,rank):
if phase%2 == 0:
if rank%2 == 0:
partner = rank+1
else:
partner = rank-1
else:
if rank%2 == 0:
partner = rank-1
else:
partner = rank+1
if partner < 0 or partner >= size:
return None
else:
return partner
n = int(sys.argv[1])
n_per_proc = n/size
if rank == 0:
arr = random.randint(0,2*n,n)
print "Unsorted array: "+str(arr)
else:
arr = zeros(n,dtype=int64)
comm.Bcast([arr,MPI.INT],root=0)
local_arr = split(arr,size)[rank]
comm.Barrier()
start = MPI.Wtime()
# Step 1. local sort
local_arr = sort(local_arr)
# Step 2. compare and exchange operations, check get_partner for odd
# even transposition
for phase in range(size):
partner = get_partner(phase,rank)
if partner != None :
comm.Send([local_arr,MPI.INT],dest=partner,tag=42)
partner_arr = zeros(n_per_proc,dtype=int64)
comm.Recv([partner_arr,MPI.INT],source=partner,tag=42)
merged = merge(local_arr,partner_arr)
if(rank<partner):
local_arr = merged[0:n_per_proc]
else:
local_arr = merged[n_per_proc:len(merged)]
comm.Barrier()
end_local = MPI.Wtime()
if rank == 0:
f = open('gnuplot.data','a')
f.write(str(size)+"\t"+str(end_local-start)+"\n")
f.close()
print "Time taken for local computations:" + str(end_local-start)
# Step 3. Gather all local arrays into final array
comm.Allgather([local_arr,MPI.INT],[arr,MPI.INT])
time_taken = MPI.Wtime() - start
if rank == 0:
print "Sorted array : " + str(arr)
print "Time taken after all communications:"+str(time_taken)