TensorDictBase.map#
- TensorDictBase.map(fn: Callable[[TensorCollection], TensorCollection | None], dim: int = 0, num_workers: int | None = None, *, out: TensorCollection | None = None, chunksize: int | None = None, num_chunks: int | None = None, pool: mp.Pool | None = None, generator: Generator | None = None, max_tasks_per_child: int | None = None, worker_threads: int = 1, index_with_generator: bool = False, pbar: bool = False, mp_start_method: str | None = None) Self#
Applies a function to chunks of the tensordict in worker processes, and gathers the results.
The tensordict is split along
diminto chunks,fnis called on each chunk in a pool of worker processes, and the results are joined alongdim: concatenated withtorch.cat(), or stacked whenchunksize=0. For an iterator over the results, seemap_iter().The chunks are slices of the tensordict, not copies. On a memory-mapped tensordict (see
memmap_()), the workers read them from the files without a copy, which makes it possible to process data that is larger than memory.- Parameters:
fn (Callable) – the function called on each chunk, a tensordict that holds a slice of the tensordict along
dim. It returns a tensordict, a tensor, orNone. It must be picklable: define it at the top level of a module or script, not as a lambda.dim (int, optional) – the dimension along which the tensordict is split into chunks. Defaults to
0.num_workers (int, optional) – the number of worker processes. Ignored when
poolis given. Defaults toNone, which uses one worker per CPU.
- Keyword Arguments:
out (TensorDictBase, optional) – a tensordict to write the results into, with the batch size of the result. If it is in shared memory or memory-mapped (
is_shared()oris_memmap()isTrue), the workers write into it directly; otherwise the results are sent back and written into it in the main process. Defaults toNone.chunksize (int, optional) – the size of each chunk along
dim.0passes the elements one by one, unbound alongdim. Exclusive withnum_chunks. Defaults toNone.num_chunks (int, optional) – the number of chunks. Exclusive with
chunksize. Defaults toNone: if neither is given, the tensordict is split into one chunk per worker. Use more chunks when a chunk per worker does not fit in memory.pool (multiprocessing.Pool, optional) – a pool of processes to run the job. When it is given,
num_workers,generator,max_tasks_per_child,worker_threadsandmp_start_methodare ignored. Defaults toNone, which creates a pool for the call and closes it afterwards.generator (Generator, optional) – the generator that draws the base seed of the workers. Worker
iseeds torch with the base seed plusi, and NumPy with a seed derived from both, so that the workers draw different random numbers. This makes the workers independent, not the results reproducible: which worker gets which chunk changes from call to call. Defaults toNone, which uses a newtorch.Generator, so the base seed is the same on every call, and emits aFutureWarning. Starting with TensorDict 0.17, the default will change to drawing the base seed from the global torch RNG, asDataLoaderdoes, which also advances it by one draw. Passgenerator=torch.default_generatorfor that behaviour now, orgenerator=torch.Generator()to keep the current seeds. To leave the workers unseeded, pass apool.max_tasks_per_child (int, optional) – the number of chunks a worker process handles before it is replaced by a new one. Defaults to
None, which keeps the workers for the whole call.worker_threads (int, optional) – the number of torch threads in each worker. Defaults to
1.index_with_generator (bool, optional) – if
True, each chunk is indexed when a worker asks for it, instead of all at once before the job starts. This starts faster, but indexing is slower thansplit()andchunk(), so the whole call may take longer. Defaults toFalse.pbar (bool, optional) – if
True, shows a progress bar. Needstqdm; without it, no bar is shown. Defaults toFalse.mp_start_method (str, optional) – the start method of the worker processes, for example
"fork"or"spawn". CUDA tensors cannot be shared with processes started with"fork". Defaults toNone, which uses the default start method oftorch.multiprocessing.
- Returns:
The results joined along
dim, a tensordict or a tensor depending on whatfnreturns. Whenoutis given,out. Otherwise,NoneiffnreturnsNonefor every chunk.
Examples
Run this example as a script, not in a REPL: the worker processes must import
process_data, and theif __name__ == "__main__"block keeps them from running the main code again.import torch from tensordict import TensorDict def process_data(data): # The chunks of a memory-mapped tensordict are locked: # return a new tensordict instead of adding a key to data. return data.empty().set("y", data["x"] + 1) if __name__ == "__main__": data = TensorDict({"x": torch.zeros(1, 1_000)}, [1, 1_000]).memmap_() # generator=torch.default_generator seeds the workers from # the global RNG, the default from TensorDict 0.17. data = data.map( process_data, dim=1, num_workers=2, generator=torch.default_generator ) print(data["y"][:, :10]) # tensor([[1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]])
Every tensordict class and every tensorclass has this method. For the other methods, see Methods by task.