in gym3/subproc.py [0:0]
def __init__(self, env_fn, env_kwargs=None, daemon=True):
if env_kwargs is None:
env_kwargs = {}
# tensorflow is not fork safe, and fork doesn't work on all platforms anyway
self._ctx = mp.get_context("spawn")
self._p2c, c2p = self._ctx.Pipe()
# pickle cannot pickle functions, so fallback to cloudpickle if pickle fails
last_err = None
for codec, (encode, decode) in CODECS.items():
try:
env_fn_serialized = encode(env_fn)
env_kwargs_serialized = encode(env_kwargs)
except Exception as e:
last_err = e
else:
break
else:
raise Exception(
f"all attempted encoders failed, tried: {', '.join(CODECS.keys())}. Last error was:\n {last_err}.\n\nIf you are pickling a function defined inside of another function, try `pip install cloudpickle` to enable cloudpickle encoding"
)
self._child = self._ctx.Process(
target=_worker,
kwargs=dict(
decode=decode,
env_fn_serialized=env_fn_serialized,
env_kwargs_serialized=env_kwargs_serialized,
p2c=self._p2c,
c2p=c2p,
),
daemon=daemon,
)
# clear mpi vars to avoid issues with MPI_init being called in subprocesses
with _clear_mpi_env_vars():
self._child.start()
# close child connection to avoid hangs when child exits unexpectedly
c2p.close()
result, err = self._communicate(self._p2c.recv)
if err is not None:
self.close()
raise SubprocError("failed to create env in subprocess") from Exception(
"exception in subprocess:\n\n" + err
)
ob_space, ac_space, num = result
super().__init__(ob_space=ob_space, ac_space=ac_space, num=num)