Skip to content

Commit 8ee84fe

Browse files
author
Jonathan Harper
authored
Fix environment factory pickling on Windows (#1912)
SubprocessUnityEnvironment sends an environment factory function to each worker which it can use to create a UnityEnvironment to interact with. We use Python's standard multiprocessing library, which pickles all data sent to the subprocess. The built-in pickle library doesn't pickle function objects on Windows machines (tested with Python 3.6 on Windows 10 Pro). This PR adds cloudpickle as a dependency in order to serialize the environment factory. Other implementations of subprocess environments do the same: https://github.com/openai/baselines/blob/master/baselines/common/vec_env/subproc_vec_env.py
1 parent 3902463 commit 8ee84fe

File tree

2 files changed

+10
-4
lines changed

2 files changed

+10
-4
lines changed

ml-agents-envs/mlagents/envs/subprocess_environment.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from typing import *
22
import copy
33
import numpy as np
4+
import cloudpickle
45

56
from mlagents.envs import UnityEnvironment
67
from multiprocessing import Process, Pipe
@@ -38,7 +39,8 @@ def close(self):
3839
self.process.join()
3940

4041

41-
def worker(parent_conn: Connection, env_factory: Callable[[int], UnityEnvironment], worker_id: int):
42+
def worker(parent_conn: Connection, pickled_env_factory: str, worker_id: int):
43+
env_factory: Callable[[int], UnityEnvironment] = cloudpickle.loads(pickled_env_factory)
4244
env = env_factory(worker_id)
4345

4446
def _send_response(cmd_name, payload):
@@ -85,7 +87,11 @@ def create_worker(
8587
env_factory: Callable[[int], BaseUnityEnvironment]
8688
) -> UnityEnvWorker:
8789
parent_conn, child_conn = Pipe()
88-
child_process = Process(target=worker, args=(child_conn, env_factory, worker_id))
90+
# Need to use cloudpickle for the env factory function since function objects aren't picklable
91+
# on Windows as of Python 3.6.
92+
pickled_env_factory = cloudpickle.dumps(env_factory)
93+
94+
child_process = Process(target=worker, args=(child_conn, pickled_env_factory, worker_id))
8995
child_process.start()
9096
return UnityEnvWorker(child_process, worker_id, parent_conn)
9197

ml-agents-envs/setup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
'numpy>=1.13.3,<=1.16.1',
2727
'pytest>=3.2.2,<4.0.0',
2828
'protobuf>=3.6,<3.7',
29-
'grpcio>=1.11.0,<1.12.0'],
30-
29+
'grpcio>=1.11.0,<1.12.0',
30+
'cloudpickle==0.8.1'],
3131
python_requires=">=3.5,<3.8",
3232
)

0 commit comments

Comments
 (0)