A class which manages a list of :class:`EnvRunner`. Its job is to execute them possibly in parallel and aggregate their results.
| 197 | |
| 198 | |
| 199 | class EnvRunnerManager(object): |
| 200 | """ |
| 201 | A class which manages a list of :class:`EnvRunner`. |
| 202 | Its job is to execute them possibly in parallel and aggregate their results. |
| 203 | """ |
| 204 | def __init__(self, env_runners, maximum_staleness): |
| 205 | """ |
| 206 | Args: |
| 207 | env_runners (list[EnvRunner]): |
| 208 | maximum_staleness (int): when >1 environments run in parallel, |
| 209 | the actual stepping of an environment may happen several steps |
| 210 | after calls to `EnvRunnerManager.step()`, in order to achieve better throughput. |
| 211 | """ |
| 212 | assert len(env_runners) > 0 |
| 213 | self._runners = env_runners |
| 214 | |
| 215 | if len(self._runners) > 1: |
| 216 | # Only use threads when having >1 runners. |
| 217 | self._populate_job_queue = queue.Queue(maxsize=maximum_staleness) |
| 218 | self._threads = [self._create_simulator_thread(i) for i in range(len(self._runners))] |
| 219 | for t in self._threads: |
| 220 | t.start() |
| 221 | |
| 222 | def _create_simulator_thread(self, idx): |
| 223 | # spawn a separate thread to run policy |
| 224 | def populate_job_func(): |
| 225 | exp = self._populate_job_queue.get() |
| 226 | self._runners[idx].step(exp) |
| 227 | |
| 228 | th = ShareSessionThread(LoopThread(populate_job_func, pausable=False)) |
| 229 | th.name = "SimulatorThread-{}".format(idx) |
| 230 | return th |
| 231 | |
| 232 | def step(self, exploration): |
| 233 | """ |
| 234 | Execute one step in any of the runners. |
| 235 | """ |
| 236 | if len(self._runners) > 1: |
| 237 | self._populate_job_queue.put(exploration) |
| 238 | else: |
| 239 | self._runners[0].step(exploration) |
| 240 | |
| 241 | def reset_stats(self): |
| 242 | """ |
| 243 | Returns: |
| 244 | mean, max: two stats of the runners, to be added to backend |
| 245 | """ |
| 246 | scores = list(itertools.chain.from_iterable([v.total_scores for v in self._runners])) |
| 247 | for v in self._runners: |
| 248 | v.total_scores.clear() |
| 249 | |
| 250 | try: |
| 251 | return np.mean(scores), np.max(scores) |
| 252 | except Exception: |
| 253 | logger.exception("Cannot compute total scores in EnvRunner.") |
| 254 | return None, None |
| 255 | |
| 256 |
no outgoing calls
no test coverage detected
searching dependent graphs…