Skip to main content

PyPI Downloads arXiv Read the Docs Unittest Coverage GitHub issues GitHub stars GitHub forks GitHub license

EnvPool is a C++-based batched environment pool with pybind11 and thread pool. It has high performance (~1M raw FPS with Atari games, ~3M raw FPS with MuJoCo simulator on DGX-A100) and compatible APIs (supports Gymnasium and dm_env, both sync and async, both single and multi player environment). Currently it supports:

Here are EnvPool's several highlights:

Check out our arXiv paper for more details!

Installation

PyPI

EnvPool is currently hosted on PyPI. It supports Python 3.12-3.14 on Linux, macOS, and Windows.

You can simply install EnvPool with the following command:

$ pip install envpool

After installation, open a Python console and type

import envpool
print(envpool.__version__)

If no error occurs, you have successfully installed EnvPool.

Platform notes:

  • Linux MuJoCo wheels use the system EGL/OpenGL runtime. For Mesa on Ubuntu, install libegl1 libopengl0 libgl1-mesa-dri.
  • Linux Procgen wheels intentionally do not vendor Qt. If making a Procgen environment reports missing libQt5Core.so.5 or libQt5Gui.so.5, install the system Qt 5 runtime, for example with apt install qtbase5-dev or dnf install qt5-qtbase.
  • Windows Procgen wheels bundle the required Qt runtime DLLs (Qt5Core.dll and Qt5Gui.dll) next to the extension module.
  • Windows source/release CI validates MuJoCo rendering with Mesa software OpenGL. To reproduce that setup locally, point ENVPOOL_DLL_DIR at a Mesa DLL directory and set GALLIUM_DRIVER=llvmpipe plus MESA_GL_VERSION_OVERRIDE=4.5COMPAT.
  • Building from source still requires platform-local build dependencies, including Qt 5. The full per-platform setup is documented in Build From Source.

From Source

Please refer to the guideline.

Documentation

The tutorials and API documentation are hosted on envpool.readthedocs.io.

The example scripts are under examples/ folder; benchmark scripts are under benchmark/ folder.

Benchmark Results

The historical benchmark tables below were produced with ALE Atari environment PongNoFrameskip-v4 (with environment wrappers from OpenAI Baselines) and MuJoCo environment Ant-v3 on different hardware setups, including a TPUv3-8 virtual machine (VM) of 96 CPU cores and 2 NUMA nodes, and an NVIDIA DGX-A100 of 256 CPU cores with 8 NUMA nodes. The current scripts under benchmark/ use Gymnasium's ALE/Pong-v5 and Ant-v5. Baselines include 1) naive Python for-loop; 2) the most popular RL environment parallelization execution by Python subprocess, e.g., gym.vector_env; 3) to our knowledge, the fastest RL environment executor Sample Factory before EnvPool.

We report EnvPool performance with sync mode, async mode, and NUMA + async mode, compared with the baselines on different number of workers (i.e., number of CPU cores). As we can see from the results, EnvPool achieves significant improvements over the baselines on all settings. On the high-end setup, EnvPool achieves 1 Million frames per second with Atari and 3 Million frames per second with MuJoCo on 256 CPU cores, which is 14.9x / 19.6x of the gym.vector_env baseline. On a typical PC setup with 12 CPU cores, EnvPool's throughput is 3.1x / 2.9x of gym.vector_env.

Atari Highest FPS Laptop (12) Workstation (32) TPU-VM (96) DGX-A100 (256)
For-loop 4,893 7,914 3,993 4,640
Subprocess 15,863 47,699 46,910 71,943
Sample-Factory 28,216 138,847 222,327 707,494
EnvPool (sync) 37,396 133,824 170,380 427,851
EnvPool (async) 49,439 200,428 359,559 891,286
EnvPool (numa+async) / / 373,169 1,069,922
MuJoCo Highest FPS Laptop (12) Workstation (32) TPU-VM (96) DGX-A100 (256)
For-loop 12,861 20,298 10,474 11,569
Subprocess 36,586 105,432 87,403 163,656
Sample-Factory 62,510 309,264 461,515 1,573,262
EnvPool (sync) 66,622 380,950 296,681 949,787
EnvPool (async) 105,126 582,446 887,540 2,363,864
EnvPool (numa+async) / / 896,830 3,134,287

Please refer to the benchmark page for more details.

API Usage

The following content shows both synchronous and asynchronous API usage of EnvPool. You can also run the full script at examples/env_step.py

Synchronous API

import envpool
import numpy as np

# make Gymnasium env
env = envpool.make("Pong-v5", env_type="gymnasium", num_envs=100)
# or use envpool.make_gymnasium(...)
obs = env.reset()  # should be (100, 4, 84, 84)
act = np.zeros(100, dtype=int)
obs, rew, term, trunc, info = env.step(act)

Under the synchronous mode, envpool closely resembles Gymnasium and dm_env. It has the reset and step functions with the same meaning. However, there is one exception in envpool: batch interaction is the default. Therefore, during the creation of the envpool, there is a num_envs argument that denotes how many envs you like to run in parallel.

env = envpool.make("Pong-v5", env_type="gymnasium", num_envs=100)

The first dimension of action passed to the step function should equal num_envs.

act = np.zeros(100, dtype=int)

You don't need to manually reset one environment when any of done is true; instead, all envs in envpool have enabled auto-reset by default.

Asynchronous API

import envpool
import numpy as np

# make asynchronous
num_envs = 64
batch_size = 16
env = envpool.make(
    "Pong-v5", env_type="gymnasium", num_envs=num_envs, batch_size=batch_size
)
action_num = env.action_space.n
env.async_reset()  # send the initial reset signal to all envs
while True:
    obs, rew, term, trunc, info = env.recv()
    env_id = info["env_id"]
    action = np.random.randint(action_num, size=batch_size)
    env.send(action, env_id)

In the asynchronous mode, the step function is split into two parts: the send/recv functions. send takes two arguments, a batch of action, and the corresponding env_id that each action should be sent to. Unlike step, send does not wait for the envs to execute and return the next state, it returns immediately after the actions are fed to the envs. (The reason why it is called async mode).

env.send(action, env_id)

To get the "next states", we need to call the recv function. However, recv does not guarantee that you will get back the "next states" of the envs you just called send on. Instead, whatever envs finishes execution gets recved first.

state = env.recv()

Besides num_envs, there is one more argument batch_size. While num_envs defines how many envs in total are managed by the envpool, batch_size specifies the number of envs involved each time we interact with envpool. e.g. There are 64 envs executing in the envpool, send and recv each time interacts with a batch of 16 envs.

envpool.make("Pong-v5", env_type="gymnasium", num_envs=64, batch_size=16)

There are other configurable arguments with envpool.make; please check out EnvPool Python interface introduction.

Rendering

EnvPool exposes rendering through the Python wrapper. Create the env with render_mode="rgb_array" to get batched RGB output, or render_mode="human" to display a single env through OpenCV.

import envpool

env = envpool.make(
    "Ant-v5",
    env_type="gymnasium",
    num_envs=4,
    render_mode="rgb_array",
    render_width=480,
    render_height=480,
)
env.reset()
frames = env.render(env_ids=[0, 2])
assert frames.shape == (2, 480, 480, 3)

render() is batch-first, so even a single render keeps the batch dimension: env.render().shape == (1, H, W, 3). If env_ids is omitted, EnvPool renders render_env_id (default 0). camera_id can be overridden per call, while the output size is fixed at env creation time via render_width and render_height.

The repo test suite also exercises rendering. make bazel-test runs repeated render checks for every render-capable env family, and make release-test includes a wheel smoke that calls render() after reset(). On Windows, the MuJoCo render tests use the same ENVPOOL_DLL_DIR Mesa preload hook described above when you want software OpenGL instead of the system driver.

viewer = envpool.make(
    "WalkerWalk-v1",
    env_type="gymnasium",
    num_envs=1,
    render_mode="human",
    render_env_id=0,
)
viewer.reset()
viewer.render()

render_mode="human" returns None and currently supports a single env id per call. It also requires opencv-python to be installed.

Pixel Observations

For MuJoCo tasks, pixel observations can also be exposed directly through the regular observation API by passing from_pixels=True. This path is produced natively in C++, without routing through Python-side render().

pixels = envpool.make(
    "WalkerWalk-v1",
    env_type="gymnasium",
    num_envs=2,
    from_pixels=True,
    frame_stack=3,
    render_width=84,
    render_height=84,
)
obs, info = pixels.reset()
assert obs.shape == (2, 9, 84, 84)

Pixel observations use channel-first layout. With frame_stack=1, each environment returns (3, H, W); with frame_stack=3, EnvPool stacks frames on the channel dimension and returns (9, H, W). This matches the usual PyTorch BCHW convention directly. If render_width / render_height are omitted, EnvPool defaults them to 84.

Contributing

EnvPool is still under development. More environments will be added, and we always welcome contributions to help EnvPool better. If you would like to contribute, please check out our contribution guideline.

License

EnvPool is under Apache2 license.

Other third-party source-code and data are under their corresponding licenses.

We do not include their source code and data in this repo.

Citing EnvPool

If you find EnvPool useful, please cite it in your publications.

@inproceedings{weng2022envpool,
 author = {Weng, Jiayi and Lin, Min and Huang, Shengyi and Liu, Bo and Makoviichuk, Denys and Makoviychuk, Viktor and Liu, Zichen and Song, Yufan and Luo, Ting and Jiang, Yukun and Xu, Zhongwen and Yan, Shuicheng},
 booktitle = {Advances in Neural Information Processing Systems},
 editor = {S. Koyejo and S. Mohamed and A. Agarwal and D. Belgrave and K. Cho and A. Oh},
 pages = {22409--22421},
 publisher = {Curran Associates, Inc.},
 title = {Env{P}ool: A Highly Parallel Reinforcement Learning Environment Execution Engine},
 url = {https://proceedings.neurips.cc/paper_files/paper/2022/file/8caaf08e49ddbad6694fae067442ee21-Paper-Datasets_and_Benchmarks.pdf},
 volume = {35},
 year = {2022}
}

Disclaimer

This is not an official Sea Limited or Garena Online Private Limited product.

Metadata

Release files for envpool 1.2.8

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distributions (wheels)

Table of built distributions (wheels) for envpool 1.2.8
File Actions
envpool-1.2.8-cp314-cp314-win_amd64.whl CPython 3.14 CPython 3.14 Windows x86-64 Details for envpool-1.2.8-cp314-cp314-win_amd64.whl
envpool-1.2.8-cp314-cp314-manylinux_2_28_x86_64.whl CPython 3.14 CPython 3.14 Linux glibc 2.28+ x86-64 Details for envpool-1.2.8-cp314-cp314-manylinux_2_28_x86_64.whl
envpool-1.2.8-cp314-cp314-manylinux_2_28_aarch64.whl CPython 3.14 CPython 3.14 Linux glibc 2.28+ ARM64 Details for envpool-1.2.8-cp314-cp314-manylinux_2_28_aarch64.whl
envpool-1.2.8-cp314-cp314-macosx_13_0_arm64.whl CPython 3.14 CPython 3.14 macOS 13.0+ ARM64 Details for envpool-1.2.8-cp314-cp314-macosx_13_0_arm64.whl
envpool-1.2.8-cp313-cp313-win_amd64.whl CPython 3.13 CPython 3.13 Windows x86-64 Details for envpool-1.2.8-cp313-cp313-win_amd64.whl
envpool-1.2.8-cp313-cp313-manylinux_2_28_x86_64.whl CPython 3.13 CPython 3.13 Linux glibc 2.28+ x86-64 Details for envpool-1.2.8-cp313-cp313-manylinux_2_28_x86_64.whl
envpool-1.2.8-cp313-cp313-manylinux_2_28_aarch64.whl CPython 3.13 CPython 3.13 Linux glibc 2.28+ ARM64 Details for envpool-1.2.8-cp313-cp313-manylinux_2_28_aarch64.whl
envpool-1.2.8-cp313-cp313-macosx_13_0_arm64.whl CPython 3.13 CPython 3.13 macOS 13.0+ ARM64 Details for envpool-1.2.8-cp313-cp313-macosx_13_0_arm64.whl
envpool-1.2.8-cp312-cp312-win_amd64.whl CPython 3.12 CPython 3.12 Windows x86-64 Details for envpool-1.2.8-cp312-cp312-win_amd64.whl
envpool-1.2.8-cp312-cp312-manylinux_2_28_x86_64.whl CPython 3.12 CPython 3.12 Linux glibc 2.28+ x86-64 Details for envpool-1.2.8-cp312-cp312-manylinux_2_28_x86_64.whl
envpool-1.2.8-cp312-cp312-manylinux_2_28_aarch64.whl CPython 3.12 CPython 3.12 Linux glibc 2.28+ ARM64 Details for envpool-1.2.8-cp312-cp312-manylinux_2_28_aarch64.whl
envpool-1.2.8-cp312-cp312-macosx_13_0_arm64.whl CPython 3.12 CPython 3.12 macOS 13.0+ ARM64 Details for envpool-1.2.8-cp312-cp312-macosx_13_0_arm64.whl

Total release size: 655.7 MB

Release files / envpool-1.2.8-cp314-cp314-win_amd64.whl

Download URL envpool-1.2.8-cp314-cp314-win_amd64.whl
Size 45.4 MB
Tags CPython 3.14 Windows x86-64
SHA-256 checksum
How to use checksums
6782822f5f05f7021c999d3abcef4b8bc83a76dce86cb7f72073ee1cef17eca8
BLAKE2b-256 checksum
How to use checksums
048a25ba6e4fe3fdcc25098f3e8ffe7bc712059b48907844d50bc2fa5d8e0f94
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.9

Release files / envpool-1.2.8-cp314-cp314-manylinux_2_28_x86_64.whl

Download URL envpool-1.2.8-cp314-cp314-manylinux_2_28_x86_64.whl
Size 64.3 MB
Tags CPython 3.14 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
281f97221f73e9ad005296066ed8939e0a424df42f9753647edccbed5380461c
BLAKE2b-256 checksum
How to use checksums
c3b3dabfc782b47306de5cc100250a8321a7e5c13867670d71e5542d205a9f14
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.9

Release files / envpool-1.2.8-cp314-cp314-manylinux_2_28_aarch64.whl

Download URL envpool-1.2.8-cp314-cp314-manylinux_2_28_aarch64.whl
Size 62.4 MB
Tags CPython 3.14 Linux glibc 2.28+ ARM64
SHA-256 checksum
How to use checksums
3cb862431d4e65dc511a356350ad85ed08e88dd6759f9d8e57845013f4922f93
BLAKE2b-256 checksum
How to use checksums
087d85ae5b1ca8148f47636711a88115e92fd6fade4d3aa8bf5290ce34477ba0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.9

Release files / envpool-1.2.8-cp314-cp314-macosx_13_0_arm64.whl

Download URL envpool-1.2.8-cp314-cp314-macosx_13_0_arm64.whl
Size 47.0 MB
Tags CPython 3.14 macOS 13.0+ ARM64
SHA-256 checksum
How to use checksums
51c9e98c2cbac3503bbfa7a218a89401ba1255eb3dbe78484cee1044a3095b87
BLAKE2b-256 checksum
How to use checksums
129f51a1cbc6fff9578d5b975b8cf49a7c56957e3cb55af728937cdb8cd861ac
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.9

Release files / envpool-1.2.8-cp313-cp313-win_amd64.whl

Download URL envpool-1.2.8-cp313-cp313-win_amd64.whl
Size 44.5 MB
Tags CPython 3.13 Windows x86-64
SHA-256 checksum
How to use checksums
8c7a944b2ceb4b02f12e7387afc610fff297d791f8d6d58e231ab40e495f8d5b
BLAKE2b-256 checksum
How to use checksums
112f8a8db880c2d17e6f51b81f15df5ccbe1beeec6b4d6a7f1e9c71fa940699b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.9

Release files / envpool-1.2.8-cp313-cp313-manylinux_2_28_x86_64.whl

Download URL envpool-1.2.8-cp313-cp313-manylinux_2_28_x86_64.whl
Size 64.3 MB
Tags CPython 3.13 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
1a8e83f3f9317ddf386f9573b066e916b60aece9e79aa90b2660653ee81d5ab2
BLAKE2b-256 checksum
How to use checksums
e3ab1e95320cfe85e66c576a0099110b8d32ccd1c737e2ed01f0e609f3c0a1c2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.9

Release files / envpool-1.2.8-cp313-cp313-manylinux_2_28_aarch64.whl

Download URL envpool-1.2.8-cp313-cp313-manylinux_2_28_aarch64.whl
Size 62.4 MB
Tags CPython 3.13 Linux glibc 2.28+ ARM64
SHA-256 checksum
How to use checksums
161dcd1863c4db45dffbb58b4bbc09939661ae46c00c07b87b8b22bedc855d67
BLAKE2b-256 checksum
How to use checksums
33240952089ec21a4917d79f9c11cc9c66fd20341aadb032610e911053b3169c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.9

Release files / envpool-1.2.8-cp313-cp313-macosx_13_0_arm64.whl

Download URL envpool-1.2.8-cp313-cp313-macosx_13_0_arm64.whl
Size 47.0 MB
Tags CPython 3.13 macOS 13.0+ ARM64
SHA-256 checksum
How to use checksums
69cba20ccded7f06192860f9c27dc776792380bb9e7308af3da878de578361aa
BLAKE2b-256 checksum
How to use checksums
8765341c5f9a543ec06a237019e83e5a872f720382933176116f8078f9536904
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.9

Release files / envpool-1.2.8-cp312-cp312-win_amd64.whl

Download URL envpool-1.2.8-cp312-cp312-win_amd64.whl
Size 44.5 MB
Tags CPython 3.12 Windows x86-64
SHA-256 checksum
How to use checksums
0338b47c362dcc7d9144e78ae33ef2fda309e50625f6dd16bdb8d32ded9dc507
BLAKE2b-256 checksum
How to use checksums
8942c703512d8ac573c7de62b5ceb69f7febdf55dc943682d0fe42c3428dfda9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.9

Release files / envpool-1.2.8-cp312-cp312-manylinux_2_28_x86_64.whl

Download URL envpool-1.2.8-cp312-cp312-manylinux_2_28_x86_64.whl
Size 64.3 MB
Tags CPython 3.12 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
974d806f6cd021b4f30659e83d7a5e43e2725f63c4a690de384e3ae3a83f8ef1
BLAKE2b-256 checksum
How to use checksums
8c944b8ea81c26b4170a24edf4a8e7744d15c09c810ddf94f774e91809e80285
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.9

Release files / envpool-1.2.8-cp312-cp312-manylinux_2_28_aarch64.whl

Download URL envpool-1.2.8-cp312-cp312-manylinux_2_28_aarch64.whl
Size 62.4 MB
Tags CPython 3.12 Linux glibc 2.28+ ARM64
SHA-256 checksum
How to use checksums
a9861423ca8d0b8efa7f99505fd3c831e9cb569d7ee0e6a98a96a56f37429a91
BLAKE2b-256 checksum
How to use checksums
f73199c462e1f0c5689ac34eb7f19d0724f1628caa93af94b39f180dc1189650
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.9

Release files / envpool-1.2.8-cp312-cp312-macosx_13_0_arm64.whl

Download URL envpool-1.2.8-cp312-cp312-macosx_13_0_arm64.whl
Size 47.0 MB
Tags CPython 3.12 macOS 13.0+ ARM64
SHA-256 checksum
How to use checksums
5f51a186cdf13664f23e87bb57ab1f63ac717cdb229a9bd9b8e1a7592311fccd
BLAKE2b-256 checksum
How to use checksums
c33863be7157aa78388438a04011bbf8c14026271285a8072b9abdd91f9f092d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.9

Security for envpool 1.2.8

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page