@@ -72,14 +72,14 @@ Some libraries such as `gym3 <https://github.com/openai/gym3>`_ or `EnvPool <htt
72
72
offer interfaces to execute batches of environments simultaneously.
73
73
While they often offer a very competitive computational advantage, they do not
74
74
necessarily scale to the wide variety of environment libraries supported by TorchRL.
75
- Therefore, TorchRL offers its own, generic :obj : `ParallelEnv ` class to run multiple
75
+ Therefore, TorchRL offers its own, generic :class : `ParallelEnv ` class to run multiple
76
76
environments in parallel.
77
- As this class inherits from :obj: ` EnvBase `, it enjoys the exact same API as other environment.
78
- Of course, a :obj : `ParallelEnv ` will have a batch size that corresponds to its environment count:
77
+ As this class inherits from :class: ` SerialEnv `, it enjoys the exact same API as other environment.
78
+ Of course, a :class : `ParallelEnv ` will have a batch size that corresponds to its environment count:
79
79
80
80
It is important that your environment specs match the input and output that it sends and receives, as
81
- :obj : `ParallelEnv ` will create buffers from these specs to communicate with the spawn processes.
82
- Check the :obj : `torchrl.envs.utils.check_env_specs ` method for a sanity check.
81
+ :class : `ParallelEnv ` will create buffers from these specs to communicate with the spawn processes.
82
+ Check the :func : `torchrl.envs.utils.check_env_specs ` method for a sanity check.
83
83
84
84
.. code-block ::
85
85
:caption: Parallel environment
@@ -91,7 +91,7 @@ Check the :obj:`torchrl.envs.utils.check_env_specs` method for a sanity check.
91
91
>>> print(env.batch_size)
92
92
torch.Size([4])
93
93
94
- :obj : `ParallelEnv ` allows to retrieve the attributes from its contained environments:
94
+ :class : `ParallelEnv ` allows to retrieve the attributes from its contained environments:
95
95
one can simply call:
96
96
97
97
.. code-block ::
@@ -118,29 +118,29 @@ It is also possible to reset some but not all of the environments:
118
118
is_shared=True)
119
119
120
120
121
- *A note on performance *: launching a :obj : `ParallelEnv ` can take quite some time
121
+ *A note on performance *: launching a :class : `ParallelEnv ` can take quite some time
122
122
as it requires to launch as many python instances as there are processes. Due to
123
- the time that it takes to run :obj: ` import torch ` (and other imports), starting the
123
+ the time that it takes to run `` import torch ` ` (and other imports), starting the
124
124
parallel env can be a bottleneck. This is why, for instance, TorchRL tests are so slow.
125
125
Once the environment is launched, a great speedup should be observed.
126
126
127
- Another thing to take in consideration is that :obj : `ParallelEnv`s (as well as data collectors)
127
+ Another thing to take in consideration is that :class : `ParallelEnv`s (as well as data collectors)
128
128
will create data buffers based on the environment specs to pass data from one process
129
129
to another. This means that a misspecified spec (input, observation or reward) will
130
130
cause a breakage at runtime as the data can't be written on the preallocated buffer.
131
131
In general, an environment should be tested using the :obj:`check_env_specs `
132
- test function before being used in a :obj : `ParallelEnv `. This function will raise
132
+ test function before being used in a :class : `ParallelEnv `. This function will raise
133
133
an assertion error whenever the preallocated buffer and the collected data mismatch.
134
134
135
- We also offer the :obj : `SerialEnv ` class that enjoys the exact same API but is executed
135
+ We also offer the :class : `SerialEnv ` class that enjoys the exact same API but is executed
136
136
serially. This is mostly useful for testing purposes, when one wants to assess the
137
- behaviour of a :obj : `ParallelEnv ` without launching the subprocesses.
137
+ behaviour of a :class : `ParallelEnv ` without launching the subprocesses.
138
138
139
- In addition to :obj : `ParallelEnv `, which offers process-based parallelism, we also provide a way to create
139
+ In addition to :class : `ParallelEnv `, which offers process-based parallelism, we also provide a way to create
140
140
multithreaded environments with :obj: `MultiThreadedEnv `. This class uses `EnvPool <https://github.com/sail-sg/envpool >`_
141
141
library underneath, which allows for higher performance, but at the same time restricts flexibility - one can only
142
142
create environments implemented in `EnvPool `. This covers many popular RL environments types (Atari, Classic Control,
143
- etc.), but one can not use an arbitrary TorchRL environment, as it is possible with :obj : `ParallelEnv `. Run
143
+ etc.), but one can not use an arbitrary TorchRL environment, as it is possible with :class : `ParallelEnv `. Run
144
144
`benchmarks/benchmark_batched_envs.py ` to compare performance of different ways to parallelize batched environments.
145
145
146
146
.. autosummary ::
@@ -161,8 +161,8 @@ In most cases, the raw output of an environment must be treated before being pas
161
161
policy or a value operator). To do this, TorchRL provides a set of transforms that aim at reproducing the transform
162
162
logic of `torch.distributions.Transform ` and `torchvision.transforms `.
163
163
164
- Transformed environments are build using the :doc : `TransformedEnv ` primitive.
165
- Composed transforms are built using the :doc : `Compose ` class:
164
+ Transformed environments are build using the :class : `TransformedEnv ` primitive.
165
+ Composed transforms are built using the :class : `Compose ` class:
166
166
167
167
.. code-block ::
168
168
:caption: Transformed environment
@@ -179,7 +179,7 @@ operations that is to be computed.
179
179
180
180
A great advantage of environment wrappers is that one can consult the environment up to that wrapper.
181
181
The same can be achieved with TorchRL transformed environments: the :doc: `parent ` attribute will
182
- return a new :obj : `TransformedEnv ` with all the transforms up to the transform of interest.
182
+ return a new :class : `TransformedEnv ` with all the transforms up to the transform of interest.
183
183
Re-using the example above:
184
184
185
185
.. code-block ::
@@ -213,17 +213,17 @@ in mind that the parent may come and go following what is being done with the tr
213
213
Here are some examples: if we get a single transform from a :class: `Compose ` object,
214
214
this transform will keep its parent:
215
215
216
- >>> third_transform = env.transform[2 ]
217
- >>> assert third_transform.parent is not None
216
+ >>> third_transform = env.transform[2 ]
217
+ >>> assert third_transform.parent is not None
218
218
219
219
This means that using this transform for another environment is prohibited, as
220
220
the other environment would replace the parent and this may lead to unexpected
221
221
behviours. Fortunately, the :class: `Transform ` class comes with a :func: `clone `
222
222
method that will erase the parent while keeping the identity of all the
223
223
registered buffers:
224
224
225
- >>> TransformedEnv(base_env, third_transform) # raises an Exception as third_transform already has a parent
226
- >>> TransformedEnv(base_env, third_transform.clone()) # works
225
+ >>> TransformedEnv(base_env, third_transform) # raises an Exception as third_transform already has a parent
226
+ >>> TransformedEnv(base_env, third_transform.clone()) # works
227
227
228
228
On a single process or if the buffers are placed in shared memory, this will
229
229
result in all the clone transforms to keep the same behaviour even if the
@@ -237,14 +237,14 @@ indexing a :class:`Compose` transform results in another :class:`Compose` transf
237
237
that does not have a parent environment. Hence, we have to clone the sub-transforms
238
238
to be able to create this other composition:
239
239
240
- >>> env = TransformedEnv(base_env, Compose(transform1, transform2, transform3))
241
- >>> last_two = env.transform[- 2 :]
242
- >>> assert isinstance (last_two, Compose)
243
- >>> assert last_two.parent is None
244
- >>> assert last_two[0 ] is not transform2
245
- >>> assert isinstance (last_two[0 ], transform2) # and the buffers will match
246
- >>> assert last_two[1 ] is not transform3
247
- >>> assert isinstance (last_two[1 ], transform3) # and the buffers will match
240
+ >>> env = TransformedEnv(base_env, Compose(transform1, transform2, transform3))
241
+ >>> last_two = env.transform[- 2 :]
242
+ >>> assert isinstance (last_two, Compose)
243
+ >>> assert last_two.parent is None
244
+ >>> assert last_two[0 ] is not transform2
245
+ >>> assert isinstance (last_two[0 ], type ( transform2) ) # and the buffers will match
246
+ >>> assert last_two[1 ] is not transform3
247
+ >>> assert isinstance (last_two[1 ], type ( transform3) ) # and the buffers will match
248
248
249
249
.. autosummary ::
250
250
:toctree: generated/
0 commit comments