Skip to content

Commit 08a277a

Browse files
authored
style: preserve upstream LF line endings
1 parent 1dc23e6 commit 08a277a

1 file changed

Lines changed: 196 additions & 196 deletions

File tree

Lines changed: 196 additions & 196 deletions
Original file line numberDiff line numberDiff line change
@@ -1,196 +1,196 @@
1-
"""
2-
This is an implementation of odd-even transposition sort.
3-
4-
It works by performing a series of parallel swaps between odd and even pairs of
5-
variables in the list.
6-
7-
This implementation represents each variable in the list with a process and
8-
each process communicates with its neighboring processes in the list to perform
9-
comparisons.
10-
They are synchronized with locks and message passing but other forms of
11-
synchronization could be used.
12-
"""
13-
14-
import multiprocessing as mp
15-
16-
# lock used to ensure that two processes do not access a pipe at the same time
17-
# NOTE This breaks testing on build runner. May work better locally
18-
# process_lock = mp.Lock()
19-
20-
"""
21-
The function run by the processes that sorts the list
22-
23-
position = the position in the list the process represents, used to know which
24-
neighbor we pass our value to
25-
value = the initial value at list[position]
26-
LSend, RSend = the pipes we use to send to our left and right neighbors
27-
LRcv, RRcv = the pipes we use to receive from our left and right neighbors
28-
resultPipe = the pipe used to send results back to main
29-
"""
30-
31-
32-
def oe_process(
33-
position,
34-
value,
35-
l_send,
36-
r_send,
37-
lr_cv,
38-
rr_cv,
39-
result_pipe,
40-
multiprocessing_context,
41-
phases: int,
42-
) -> None:
43-
process_lock = multiprocessing_context.Lock()
44-
45-
# we perform n swaps since after n swaps we know we are sorted
46-
# we *could* stop early if we are sorted already, but it takes as long to
47-
# find out we are sorted as it does to sort the list with this algorithm
48-
for i in range(phases):
49-
if (i + position) % 2 == 0 and r_send is not None:
50-
# send your value to your right neighbor
51-
with process_lock:
52-
r_send[1].send(value)
53-
54-
# receive your right neighbor's value
55-
with process_lock:
56-
temp = rr_cv[0].recv()
57-
58-
# take the lower value since you are on the left
59-
value = min(value, temp)
60-
elif (i + position) % 2 != 0 and l_send is not None:
61-
# send your value to your left neighbor
62-
with process_lock:
63-
l_send[1].send(value)
64-
65-
# receive your left neighbor's value
66-
with process_lock:
67-
temp = lr_cv[0].recv()
68-
69-
# take the higher value since you are on the right
70-
value = max(value, temp)
71-
# after all swaps are performed, send the values back to main
72-
result_pipe[1].send(value)
73-
74-
75-
"""
76-
the function which creates the processes that perform the parallel swaps
77-
78-
arr = the list to be sorted
79-
"""
80-
81-
82-
def odd_even_transposition(arr):
83-
"""
84-
>>> odd_even_transposition(list(range(10)[::-1])) == sorted(list(range(10)[::-1]))
85-
True
86-
>>> odd_even_transposition(["a", "x", "c"]) == sorted(["x", "a", "c"])
87-
True
88-
>>> odd_even_transposition([1.9, 42.0, 2.8]) == sorted([1.9, 42.0, 2.8])
89-
True
90-
>>> odd_even_transposition([False, True, False]) == sorted([False, False, True])
91-
True
92-
>>> odd_even_transposition([1, 32.0, 9]) == sorted([False, False, True])
93-
False
94-
>>> odd_even_transposition([1, 32.0, 9]) == sorted([1.0, 32, 9.0])
95-
True
96-
>>> unsorted_list = [-442, -98, -554, 266, -491, 985, -53, -529, 82, -429]
97-
>>> odd_even_transposition(unsorted_list) == sorted(unsorted_list)
98-
True
99-
>>> unsorted_list = [-442, -98, -554, 266, -491, 985, -53, -529, 82, -429]
100-
>>> odd_even_transposition(unsorted_list) == sorted(unsorted_list + [1])
101-
False
102-
"""
103-
# spawn method is considered safer than fork
104-
multiprocessing_context = mp.get_context("spawn")
105-
106-
process_array_ = []
107-
result_pipe = []
108-
# initialize the list of pipes where the values will be retrieved
109-
for _ in arr:
110-
result_pipe.append(multiprocessing_context.Pipe())
111-
# creates the processes
112-
# the first and last process only have one neighbor so they are made outside
113-
# of the loop
114-
temp_rs = multiprocessing_context.Pipe()
115-
temp_rr = multiprocessing_context.Pipe()
116-
process_array_.append(
117-
multiprocessing_context.Process(
118-
target=oe_process,
119-
args=(
120-
0,
121-
arr[0],
122-
None,
123-
temp_rs,
124-
None,
125-
temp_rr,
126-
result_pipe[0],
127-
multiprocessing_context,
128-
len(arr),
129-
),
130-
)
131-
)
132-
temp_lr = temp_rs
133-
temp_ls = temp_rr
134-
135-
for i in range(1, len(arr) - 1):
136-
temp_rs = multiprocessing_context.Pipe()
137-
temp_rr = multiprocessing_context.Pipe()
138-
process_array_.append(
139-
multiprocessing_context.Process(
140-
target=oe_process,
141-
args=(
142-
i,
143-
arr[i],
144-
temp_ls,
145-
temp_rs,
146-
temp_lr,
147-
temp_rr,
148-
result_pipe[i],
149-
multiprocessing_context,
150-
len(arr),
151-
),
152-
)
153-
)
154-
temp_lr = temp_rs
155-
temp_ls = temp_rr
156-
157-
process_array_.append(
158-
multiprocessing_context.Process(
159-
target=oe_process,
160-
args=(
161-
len(arr) - 1,
162-
arr[len(arr) - 1],
163-
temp_ls,
164-
None,
165-
temp_lr,
166-
None,
167-
result_pipe[len(arr) - 1],
168-
multiprocessing_context,
169-
len(arr),
170-
),
171-
)
172-
)
173-
174-
# start the processes
175-
for p in process_array_:
176-
p.start()
177-
178-
# wait for the processes to end and write their values to the list
179-
for p in range(len(result_pipe)):
180-
arr[p] = result_pipe[p][0].recv()
181-
process_array_[p].join()
182-
return arr
183-
184-
185-
# creates a reverse sorted list and sorts it
186-
def main() -> None:
187-
arr = list(range(10, 0, -1))
188-
print("Initial List")
189-
print(*arr)
190-
arr = odd_even_transposition(arr)
191-
print("Sorted List\n")
192-
print(*arr)
193-
194-
195-
if __name__ == "__main__":
196-
main()
1+
"""
2+
This is an implementation of odd-even transposition sort.
3+
4+
It works by performing a series of parallel swaps between odd and even pairs of
5+
variables in the list.
6+
7+
This implementation represents each variable in the list with a process and
8+
each process communicates with its neighboring processes in the list to perform
9+
comparisons.
10+
They are synchronized with locks and message passing but other forms of
11+
synchronization could be used.
12+
"""
13+
14+
import multiprocessing as mp
15+
16+
# lock used to ensure that two processes do not access a pipe at the same time
17+
# NOTE This breaks testing on build runner. May work better locally
18+
# process_lock = mp.Lock()
19+
20+
"""
21+
The function run by the processes that sorts the list
22+
23+
position = the position in the list the process represents, used to know which
24+
neighbor we pass our value to
25+
value = the initial value at list[position]
26+
LSend, RSend = the pipes we use to send to our left and right neighbors
27+
LRcv, RRcv = the pipes we use to receive from our left and right neighbors
28+
resultPipe = the pipe used to send results back to main
29+
"""
30+
31+
32+
def oe_process(
33+
position,
34+
value,
35+
l_send,
36+
r_send,
37+
lr_cv,
38+
rr_cv,
39+
result_pipe,
40+
multiprocessing_context,
41+
phases: int,
42+
) -> None:
43+
process_lock = multiprocessing_context.Lock()
44+
45+
# we perform n swaps since after n swaps we know we are sorted
46+
# we *could* stop early if we are sorted already, but it takes as long to
47+
# find out we are sorted as it does to sort the list with this algorithm
48+
for i in range(phases):
49+
if (i + position) % 2 == 0 and r_send is not None:
50+
# send your value to your right neighbor
51+
with process_lock:
52+
r_send[1].send(value)
53+
54+
# receive your right neighbor's value
55+
with process_lock:
56+
temp = rr_cv[0].recv()
57+
58+
# take the lower value since you are on the left
59+
value = min(value, temp)
60+
elif (i + position) % 2 != 0 and l_send is not None:
61+
# send your value to your left neighbor
62+
with process_lock:
63+
l_send[1].send(value)
64+
65+
# receive your left neighbor's value
66+
with process_lock:
67+
temp = lr_cv[0].recv()
68+
69+
# take the higher value since you are on the right
70+
value = max(value, temp)
71+
# after all swaps are performed, send the values back to main
72+
result_pipe[1].send(value)
73+
74+
75+
"""
76+
the function which creates the processes that perform the parallel swaps
77+
78+
arr = the list to be sorted
79+
"""
80+
81+
82+
def odd_even_transposition(arr):
83+
"""
84+
>>> odd_even_transposition(list(range(10)[::-1])) == sorted(list(range(10)[::-1]))
85+
True
86+
>>> odd_even_transposition(["a", "x", "c"]) == sorted(["x", "a", "c"])
87+
True
88+
>>> odd_even_transposition([1.9, 42.0, 2.8]) == sorted([1.9, 42.0, 2.8])
89+
True
90+
>>> odd_even_transposition([False, True, False]) == sorted([False, False, True])
91+
True
92+
>>> odd_even_transposition([1, 32.0, 9]) == sorted([False, False, True])
93+
False
94+
>>> odd_even_transposition([1, 32.0, 9]) == sorted([1.0, 32, 9.0])
95+
True
96+
>>> unsorted_list = [-442, -98, -554, 266, -491, 985, -53, -529, 82, -429]
97+
>>> odd_even_transposition(unsorted_list) == sorted(unsorted_list)
98+
True
99+
>>> unsorted_list = [-442, -98, -554, 266, -491, 985, -53, -529, 82, -429]
100+
>>> odd_even_transposition(unsorted_list) == sorted(unsorted_list + [1])
101+
False
102+
"""
103+
# spawn method is considered safer than fork
104+
multiprocessing_context = mp.get_context("spawn")
105+
106+
process_array_ = []
107+
result_pipe = []
108+
# initialize the list of pipes where the values will be retrieved
109+
for _ in arr:
110+
result_pipe.append(multiprocessing_context.Pipe())
111+
# creates the processes
112+
# the first and last process only have one neighbor so they are made outside
113+
# of the loop
114+
temp_rs = multiprocessing_context.Pipe()
115+
temp_rr = multiprocessing_context.Pipe()
116+
process_array_.append(
117+
multiprocessing_context.Process(
118+
target=oe_process,
119+
args=(
120+
0,
121+
arr[0],
122+
None,
123+
temp_rs,
124+
None,
125+
temp_rr,
126+
result_pipe[0],
127+
multiprocessing_context,
128+
len(arr),
129+
),
130+
)
131+
)
132+
temp_lr = temp_rs
133+
temp_ls = temp_rr
134+
135+
for i in range(1, len(arr) - 1):
136+
temp_rs = multiprocessing_context.Pipe()
137+
temp_rr = multiprocessing_context.Pipe()
138+
process_array_.append(
139+
multiprocessing_context.Process(
140+
target=oe_process,
141+
args=(
142+
i,
143+
arr[i],
144+
temp_ls,
145+
temp_rs,
146+
temp_lr,
147+
temp_rr,
148+
result_pipe[i],
149+
multiprocessing_context,
150+
len(arr),
151+
),
152+
)
153+
)
154+
temp_lr = temp_rs
155+
temp_ls = temp_rr
156+
157+
process_array_.append(
158+
multiprocessing_context.Process(
159+
target=oe_process,
160+
args=(
161+
len(arr) - 1,
162+
arr[len(arr) - 1],
163+
temp_ls,
164+
None,
165+
temp_lr,
166+
None,
167+
result_pipe[len(arr) - 1],
168+
multiprocessing_context,
169+
len(arr),
170+
),
171+
)
172+
)
173+
174+
# start the processes
175+
for p in process_array_:
176+
p.start()
177+
178+
# wait for the processes to end and write their values to the list
179+
for p in range(len(result_pipe)):
180+
arr[p] = result_pipe[p][0].recv()
181+
process_array_[p].join()
182+
return arr
183+
184+
185+
# creates a reverse sorted list and sorts it
186+
def main() -> None:
187+
arr = list(range(10, 0, -1))
188+
print("Initial List")
189+
print(*arr)
190+
arr = odd_even_transposition(arr)
191+
print("Sorted List\n")
192+
print(*arr)
193+
194+
195+
if __name__ == "__main__":
196+
main()

0 commit comments

Comments
 (0)