forked from EPFL-LAP/fpga21-scaled-tech
-
Notifications
You must be signed in to change notification settings - Fork 0
/
parallelize.py
169 lines (137 loc) · 4.71 KB
/
parallelize.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
import os
import time
import copy
##########################################################################
class Parallel(object):
"""A class for robustly handling parallel calls to standalone scripts.
Parameters
----------
max_cpu : int
Maximum number of parallel threads.
sleep_interval : int
Number of seconds to wait between to polls for available threads.
"""
#------------------------------------------------------------------------#
def __init__(self, max_cpu, sleep_interval):
"""Constructor of the Parallel class.
"""
self.max_cpu = max_cpu
self.sleep_interval = sleep_interval
self.cmds = []
self.running = []
#------------------------------------------------------------------------#
#------------------------------------------------------------------------#
def init_cmd_pool(self, cmds):
"""Initializes the command pool.
Parameters
----------
cmds : List[str]
List of commands to be issued in parallel.
Returns
-------
None
"""
self.cmds = copy.copy(cmds)
#------------------------------------------------------------------------#
#------------------------------------------------------------------------#
def spawn_ret_pid(self, cmd):
"""Calls the command and returns the process's pid.
Parameters
----------
cmd : str
The command to run.
Returns
-------
int
pid of the worker process
Notes
-----
Taken from stackexchange (https://stackoverflow.com/questions/20218570/
how-to-determine-pid-of-process-started-via-os-system)
"""
print cmd
cmd += " & echo $! > pid"
os.system(cmd)
pid_file = open("pid", "r")
pid = int(pid_file.read())
pid_file.close()
print "pid ", pid
os.system("rm pid")
return pid
#------------------------------------------------------------------------#
#------------------------------------------------------------------------#
def poll_pids(self, clean = True):
"""Polls the list of running pids and returns the number of them
that are not alive.
Parameters
----------
clean : Optional[bool], deafult = True
Specifies if the dead pids should be popped.
Returns
-------
int
Number of dead pids.
"""
#........................................................................#
def check_pid_alive(pid):
"""Checks if the pid is alive.
Parameters
----------
pid : int
pid to check.
Returns
-------
bool
True if alive else False
Notes
-----
Taken from stackexchange (https://stackoverflow.com/questions/568271/
how-to-check-if-there-exists-a-process-with-a-given-pid-in-python)
"""
try:
os.kill(pid, 0)
except OSError:
return False
else:
return True
#........................................................................#
removal_list = []
for pid in self.running:
if not check_pid_alive(pid):
removal_list.append(pid)
if clean:
for pid in removal_list:
self.running.remove(pid)
return len(removal_list)
#------------------------------------------------------------------------#
#------------------------------------------------------------------------#
def run(self):
"""Runs the initialized pool.
Parameters
----------
None
Returns
-------
None
"""
i = 0
done = False
while i < len(self.cmds) or done:
if done:
while self.running:
self.poll_pids()
break
while len(self.running) < self.max_cpu:
self.running.append(self.spawn_ret_pid(self.cmds[i]))
i += 1
if i == len(self.cmds):
done = True
break
if done:
continue
freed = 0
while freed == 0:
freed = self.poll_pids()
time.sleep(self.sleep_interval)
#------------------------------------------------------------------------#
##########################################################################