Spatial Queries#
This module provides spatial acceleration structures for efficient geometric queries on large meshes.
The BVH (Bounding Volume Hierarchy) is an axis-aligned bounding box
tree built over mesh cells. It accelerates two key operations:
Point containment: given a set of query points, find which mesh cell (if any) contains each point
Nearest-cell search: find the closest cell to each query point
The BVH is used internally by the sampling module
(sample_data_at_points(),
find_containing_cells()) to avoid brute-force
search over all cells.
import torch
from physicsnemo.mesh.spatial import BVH
from physicsnemo.mesh.primitives.surfaces import sphere_icosahedral
mesh = sphere_icosahedral.load(subdivisions=3)
bvh = BVH.from_mesh(mesh)
query_points = torch.randn(1000, 3)
candidate_cells = bvh.find_candidate_cells(query_points)
Signed Distance Field#
signed_distance_field() computes the signed distance from a set of
query points to a triangle surface mesh, together with the closest point on the
surface for each query. It is a Mesh-typed wrapper
around the Warp-backed physicsnemo.nn.functional.signed_distance_field()
op, which runs NVIDIA Warp mesh queries on CPU and CUDA.
The sign is determined by one of two methods, selected with
use_sign_winding_number:
False(default): the angle-weighted pseudo-normal of the closest mesh feature (wp.mesh_query_point_sign_normal). This is fast and robust for watertight meshes.True: the generalized winding number (wp.mesh_query_point_sign_winding_number). This is robust for non-watertight / self-intersecting (“soup”) geometry.
import torch
from physicsnemo.mesh import Mesh
from physicsnemo.mesh.spatial import signed_distance_field
# A triangle surface mesh: (n_vertices, 3) coords + (n_faces, 3) connectivity.
mesh = Mesh(
points=torch.randn(500, 3),
cells=torch.randint(0, 500, (1000, 3)),
)
query = torch.randn(10000, 3)
sdf, hit_points, hit_faces = signed_distance_field(
mesh, query, use_sign_winding_number=True
)
# sdf: (10000,) signed distances
# hit_points: (10000, 3) closest surface points
# hit_faces: (10000,) nearest-face index into mesh.cells
API Reference#
Spatial acceleration structures for efficient queries on large meshes.
This module provides data structures and algorithms for fast spatial queries:
- BVH (Bounding Volume Hierarchy) for point-in-cell queries
- ClusterTree for dual-tree Barnes-Hut acceleration of kernel/attention operators
- Signed distance field (signed_distance_field()) over a triangle
surface mesh, backed by NVIDIA Warp mesh queries (CPU and CUDA)
- class physicsnemo.mesh.spatial.BVH(
- node_aabb_min: jaxtyping.Float[Tensor, 'n_nodes n_spatial_dims'],
- node_aabb_max: jaxtyping.Float[Tensor, 'n_nodes n_spatial_dims'],
- node_left_child: jaxtyping.Int[Tensor, 'n_nodes'],
- node_right_child: jaxtyping.Int[Tensor, 'n_nodes'],
- leaf_start: jaxtyping.Int[Tensor, 'n_nodes'],
- leaf_count: jaxtyping.Int[Tensor, 'n_nodes'],
- sorted_cell_order: jaxtyping.Int[Tensor, 'n_cells'],
- *,
- batch_size,
- device=None,
- names=None,
Bases:
object- property device: device#
Device where BVH tensors are stored.
- dumps(
- prefix: str | None = None,
- copy_existing: bool = False,
- *,
- num_threads: int = 0,
- return_early: bool = False,
- share_non_tensor: bool = False,
- robust_key: bool | None = True,
- archive: bool | None = None,
- compression: str | int | None = None,
Saves the tensordict to disk.
This function is a proxy to
memmap().
- classmethod fields()#
Return a tuple describing the fields of this dataclass.
Accepts a dataclass or an instance of one. Tuple elements are of type Field.
- find_candidate_cells(
- query_points: Float[Tensor, 'n_queries n_spatial_dims'],
- max_candidates_per_point: int | None = 32,
- aabb_tolerance: float = 1e-06,
Find candidate cells that might contain each query point.
Uses batched iterative BVH traversal where all queries are processed simultaneously in a vectorized manner.
- Parameters:
query_points (torch.Tensor) – Points to query, shape
(n_queries, n_spatial_dims).max_candidates_per_point (int | None, optional) – Maximum number of candidate cells to return per query point. Prevents memory explosion for degenerate cases. If None, no limit is applied.
aabb_tolerance (float, optional) – Tolerance for AABB intersection test. Important for degenerate cells (e.g., cells with duplicate vertices).
- Returns:
Adjacency object where candidates for query
iare atresult.indices[result.offsets[i]:result.offsets[i+1]]. Useresult.to_list()for a list-of-tensors representation.- Return type:
Adjacency
Notes
Complexity is \(O(M \log N)\) where \(M\) = queries and \(N\) = cells. All AABB tests and tree operations are fully vectorized across queries - there are no Python-level loops over individual query points. The outer loop runs once per tree level (\(O(\log N)\) iterations).
- from_csv(
- *,
- auto_batch_size: bool = False,
- batch_dims: int | None = None,
- device: device | None = None,
- batch_size: Size | None = None,
- separator: str | None = None,
- dtype: dtype | None = None,
- **kwargs,
Creates a TensorDict from a CSV file.
Requires either pandas or pyarrow to be installed.
- Parameters:
path (str or Path) – Path to the CSV file.
- Keyword Arguments:
auto_batch_size (bool, optional) – If
True, the batch size will be computed automatically. Defaults toFalse.batch_dims (int, optional) – If
auto_batch_sizeisTrue, defines how many dimensions the output tensordict should have. Defaults toNone.device (torch.device, optional) – The device for tensor data. Defaults to
None.batch_size (torch.Size, optional) – The batch size. Defaults to
[num_rows].separator (str, optional) – If provided, column names are split on this separator to create nested TensorDicts. Defaults to
None.dtype (torch.dtype, optional) – If provided, all numeric columns are cast to this dtype. Defaults to
None.**kwargs – Additional keyword arguments forwarded to the CSV reader (
pandas.read_csvorpyarrow.csv.read_csv).
- Returns:
A TensorDict representation of the CSV data.
Examples
>>> td = TensorDict.from_csv("data.csv") >>> td = TensorDict.from_csv("data.csv", separator=".", dtype=torch.float32)
- from_json(
- *,
- auto_batch_size: bool = False,
- batch_dims: int | None = None,
- device: device | None = None,
- batch_size: Size | None = None,
- separator: str | None = None,
- dtype: dtype | None = None,
- lines: bool = False,
- **kwargs,
Creates a TensorDict from a JSON file.
Supports both standard JSON (array of records) and JSON Lines format. For nested JSON objects, use
from_dict()instead.Requires pandas for best results. Falls back to stdlib
jsonfor simple cases.- Parameters:
path (str or Path) – Path to the JSON file.
- Keyword Arguments:
auto_batch_size (bool, optional) – If
True, the batch size will be computed automatically. Defaults toFalse.batch_dims (int, optional) – If
auto_batch_sizeisTrue, defines how many dimensions the output tensordict should have. Defaults toNone.device (torch.device, optional) – The device for tensor data. Defaults to
None.batch_size (torch.Size, optional) – The batch size. Defaults to
[num_rows].separator (str, optional) – If provided, column names are split on this separator to create nested TensorDicts. Defaults to
None.dtype (torch.dtype, optional) – If provided, all numeric columns are cast to this dtype. Defaults to
None.lines (bool, optional) – If
True, reads the file as JSON Lines (one JSON object per line). Defaults toFalse.**kwargs – Additional keyword arguments forwarded to the JSON reader.
- Returns:
A TensorDict representation of the JSON data.
Examples
>>> td = TensorDict.from_json("data.json") >>> td = TensorDict.from_json("data.jsonl", lines=True)
- classmethod from_mesh(mesh: Mesh, leaf_size: int = 1) BVH[source]#
Construct a BVH from a mesh using morton-code LBVH.
Cells are sorted by the morton code of their centroids, then the tree is built top-down by recursively splitting sorted segments at their midpoints. AABBs are computed in two phases: leaf AABBs via segmented reduction over cell bounds, internal AABBs via a bottom-up pass from leaves to root. The entire construction runs in O(log N) Python-level iterations.
- Parameters:
mesh (Mesh) – The mesh to build the BVH for.
leaf_size (int, optional) – Maximum number of cells per leaf node. The default of 1 minimizes candidate cells per query hit but maximizes node count (
2 * n_cells - 1nodes) and tree depth. Larger values reduce build time and memory at the cost of more candidate cells per query hit.
- Returns:
Constructed BVH ready for queries.
- Return type:
- Raises:
ValueError – If
leaf_size < 1.
- from_pandas(
- *,
- auto_batch_size: bool = False,
- batch_dims: int | None = None,
- device: device | None = None,
- batch_size: Size | None = None,
- separator: str | None = None,
- dtype: dtype | None = None,
Converts a pandas DataFrame to a TensorDict.
Numeric columns become tensors, string/object columns become
NonTensorData.- Parameters:
dataframe (pd.DataFrame) – The pandas DataFrame to convert.
- Keyword Arguments:
auto_batch_size (bool, optional) – If
True, the batch size will be computed automatically. Defaults toFalse.batch_dims (int, optional) – If
auto_batch_sizeisTrue, defines how many dimensions the output tensordict should have. Defaults toNone.device (torch.device, optional) – The device for tensor data. Defaults to
None.batch_size (torch.Size, optional) – The batch size. Defaults to
[num_rows].separator (str, optional) – If provided, column names are split on this separator to create nested TensorDicts. For example, with
separator=".", a column"obs.x"becomestd["obs", "x"]. Defaults toNone.dtype (torch.dtype, optional) – If provided, all numeric columns are cast to this dtype. Defaults to
None.
- Returns:
A TensorDict representation of the DataFrame.
Examples
>>> import pandas as pd >>> df = pd.DataFrame({"a": [1, 2, 3], "b": [4.0, 5.0, 6.0]}) >>> td = TensorDict.from_pandas(df) >>> print(td) TensorDict( fields={ a: Tensor(shape=torch.Size([3]), device=cpu, dtype=torch.int64, is_shared=False), b: Tensor(shape=torch.Size([3]), device=cpu, dtype=torch.float64, is_shared=False)}, batch_size=torch.Size([3]), device=None, is_shared=False)
- from_parquet(
- *,
- auto_batch_size: bool = False,
- batch_dims: int | None = None,
- device: device | None = None,
- batch_size: Size | None = None,
- separator: str | None = None,
- dtype: dtype | None = None,
- columns: list[str] | None = None,
- **kwargs,
Creates a TensorDict from a Parquet file.
Requires either pyarrow or pandas to be installed. Prefers pyarrow when available for better performance.
- Parameters:
path (str or Path) – Path to the Parquet file.
- Keyword Arguments:
auto_batch_size (bool, optional) – If
True, the batch size will be computed automatically. Defaults toFalse.batch_dims (int, optional) – If
auto_batch_sizeisTrue, defines how many dimensions the output tensordict should have. Defaults toNone.device (torch.device, optional) – The device for tensor data. Defaults to
None.batch_size (torch.Size, optional) – The batch size. Defaults to
[num_rows].separator (str, optional) – If provided, column names are split on this separator to create nested TensorDicts. Defaults to
None.dtype (torch.dtype, optional) – If provided, all numeric columns are cast to this dtype. Defaults to
None.columns (list of str, optional) – If provided, only read these columns from the file. Defaults to
None(all columns).**kwargs – Additional keyword arguments forwarded to the Parquet reader.
- Returns:
A TensorDict representation of the Parquet data.
Examples
>>> td = TensorDict.from_parquet("data.parquet") >>> td = TensorDict.from_parquet("data.parquet", columns=["obs", "reward"])
- from_schema(
- *,
- batch_size: Sequence[int] | Size | None = None,
- storage: str | None = None,
- device=None,
- **kwargs,
Pre-allocate a zero-filled TensorDict from a schema.
Creates a
TensorDictBasewhose storage backend is selected bystorage. Each entry inschemamaps a field name to an(element_shape, dtype)pair; the full stored shape is[*batch_size, *element_shape].- Parameters:
schema – Mapping from field name to
(element_shape, dtype).element_shapeis the per-element shape (excludingbatch_size).- Keyword Arguments:
batch_size – Overall batch dimensions prepended to every element shape. Defaults to
().storage (str or None) –
Backend selector:
None– plainTensorDictwith regular tensors."memmap"– memory-mapped tensors on disk. Passprefix=<dir>in kwargs."h5"– HDF5 viaPersistentTensorDict. Passfilename=<path>in kwargs."zarr"– zarr (requireszarr>=3.0) viaPersistentTensorDict. Passfilename=<path or store>in kwargs."shared"– CPU shared-memory tensors."redis"/"dragonfly"– delegates toTensorDictStore.from_schema().
device – Device for the resulting tensors (ignored by some backends).
**kwargs – Backend-specific arguments forwarded to the underlying constructor (e.g.
prefixfor memmap,filenamefor h5,host/portfor redis).
- Returns:
A new
TensorDictBasesubclass instance with pre-allocated (zero-filled) keys.
Examples
>>> td = TensorDict.from_schema( ... {"obs": ([84, 84, 3], torch.uint8), ... "reward": ([], torch.float32)}, ... batch_size=[1000], ... ) >>> td["obs"].shape torch.Size([1000, 84, 84, 3])
>>> import tempfile >>> with tempfile.TemporaryDirectory() as d: ... td_mm = TensorDict.from_schema( ... {"obs": ([4], torch.float32)}, ... batch_size=[8], ... storage="memmap", ... prefix=d, ... ) ... assert td_mm.is_memmap()
- classmethod from_tensordict(
- tensordict: TensorDictBase,
- non_tensordict: dict | None = None,
- safe: bool = True,
Tensor class wrapper to instantiate a new tensor class object.
- Parameters:
tensordict (TensorDictBase) – Dictionary of tensor types
non_tensordict (dict) – Dictionary with non-tensor and nested tensor class objects
safe (bool) – Whether to raise an error if the tensordict is not a TensorDictBase instance
- get(key: NestedKey, *args, **kwargs)#
Gets the value stored with the input key.
- Parameters:
key (str, tuple of str) – key to be queried. If tuple of str it is equivalent to chained calls of getattr.
default – default value if the key is not found in the tensorclass.
- Returns:
value stored with the input key
- classmethod load(prefix: str | Path, *args, **kwargs) Any#
Loads a tensordict from disk.
This class method is a proxy to
load_memmap().
- load_(prefix: str | Path, *args, **kwargs)#
Loads a tensordict from disk within the current tensordict.
This class method is a proxy to
load_memmap_().
- classmethod load_memmap(
- prefix: str | Path,
- device: device | None = None,
- non_blocking: bool = False,
- *,
- out: TensorDictBase | None = None,
- robust_key: bool | None = True,
- subpath: NestedKey | None = None,
- mode: str = 'r',
- num_threads: int = 0,
- allow_pickle: bool | None = None,
Loads a memory-mapped tensordict from disk.
- Parameters:
prefix (str or Path to folder) – the path to the folder where the saved tensordict should be fetched, or the path to a memmap archive file written through
save(..., archive=True)/ a".tdz"prefix (or packed withpack_memmap()). Archives are memory-mapped once and every leaf is exposed as a zero-copy view into the mapping: only the pages of the leaves that are actually accessed are read from disk. Unlike directory-backed tensordicts, in-place writes to the leaves of an archive-loaded tensordict do not propagate to the file.device (torch.device or equivalent, optional) – if provided, the data will be asynchronously cast to that device. Supports “meta” device, in which case the data isn’t loaded but a set of empty “meta” tensors are created. This is useful to get a sense of the total model size and structure without actually opening any file.
non_blocking (bool, optional) – if
True, synchronize won’t be called after loading tensors on device. Defaults toFalse.out (TensorDictBase, optional) – optional tensordict where the data should be written.
robust_key (bool, optional) – if
True(default), expects robust key encoding was used when saving and decodes filenames accordingly. IfFalse, uses legacy behavior. IfNone, uses the default robust behavior.subpath (NestedKey or str path, optional) – the location of a nested tensordict to load, as a nested key (e.g.
("module", "0"), with arbitrary nesting allowed as usual) or as a"/"-separated string path (e.g."module/0"). Only that subtree is loaded. Works both for directories (equivalent to appending the path toprefix) and for archives.mode (str, optional) –
"r"(default) or"r+". Only relevant when loading an archive: with"r"the archive is mapped copy-on-write and in-place writes to the leaves stay in memory; with"r+"the mapping is shared and in-place writes propagate to the file, like directory-backed tensordicts."r+"requires uncompressed, aligned tensor payloads (i.e. archives written by tensordict withoutcompression) and is not available for nested-tensor leaves. In-place writes do not update the per-entry CRC-32 stored by the zip format;load_memmap()ignores checksums, but callrefresh_archive_checksums()before handing a modified archive to tools that verify them (unzip,unpack_memmap(), …). Directory prefixes are always write-through and ignore this argument.num_threads (int, optional) – number of threads used to decompress the leaves of a compressed archive (deflate entries are inflated in parallel, which scales nearly linearly). Without compression, loading is a metadata-only operation and this argument has no effect. Defaults to
0(sequential).allow_pickle (bool, optional) – whether pickled non-tensor fields may be loaded. Pickle can execute arbitrary code, so pass
Trueonly for data from a trusted source andFalsefor untrusted data. During the 0.14 compatibility window, omitting this option loads pickle with aFutureWarning; the default will change toFalsein 0.15. Saves without a pickle sidecar do not require this option.
Examples
>>> from tensordict import TensorDict >>> td = TensorDict.fromkeys(["a", "b", "c", ("nested", "e")], 0) >>> td.memmap("./saved_td") >>> td_load = TensorDict.load_memmap("./saved_td") >>> assert (td == td_load).all()
This method also allows loading nested tensordicts.
Examples
>>> nested = TensorDict.load_memmap("./saved_td/nested") >>> assert nested["e"] == 0
A tensordict can also be loaded on “meta” device or, alternatively, as a fake tensor.
Examples
>>> import tempfile >>> td = TensorDict({"a": torch.zeros(()), "b": {"c": torch.zeros(())}}) >>> with tempfile.TemporaryDirectory() as path: ... td.save(path) ... td_load = TensorDict.load_memmap(path, device="meta") ... print("meta:", td_load) ... from torch._subclasses import FakeTensorMode ... with FakeTensorMode(): ... td_load = TensorDict.load_memmap(path) ... print("fake:", td_load) meta: TensorDict( fields={ a: Tensor(shape=torch.Size([]), device=meta, dtype=torch.float32, is_shared=False), b: TensorDict( fields={ c: Tensor(shape=torch.Size([]), device=meta, dtype=torch.float32, is_shared=False)}, batch_size=torch.Size([]), device=meta, is_shared=False)}, batch_size=torch.Size([]), device=meta, is_shared=False) fake: TensorDict( fields={ a: FakeTensor(shape=torch.Size([]), device=cpu, dtype=torch.float32, is_shared=False), b: TensorDict( fields={ c: FakeTensor(shape=torch.Size([]), device=cpu, dtype=torch.float32, is_shared=False)}, batch_size=torch.Size([]), device=cpu, is_shared=False)}, batch_size=torch.Size([]), device=cpu, is_shared=False)
- load_state_dict(
- state_dict: dict[str, Any],
- strict=True,
- assign=False,
- from_flatten=None,
Loads a state_dict into the tensorclass.
Supports both the new format (logical keys with
_metadata) and the legacy format (_tensordict/_non_tensordictwrapper keys).
- memmap(
- prefix: str | None = None,
- copy_existing: bool = False,
- *,
- num_threads: int = 0,
- return_early: bool = False,
- share_non_tensor: bool = False,
- existsok: bool = True,
- robust_key: bool | None = True,
- archive: bool | None = None,
- compression: str | int | None = None,
Writes all tensors onto a corresponding memory-mapped Tensor in a new tensordict.
- Parameters:
prefix (str) – directory prefix where the memory-mapped tensors will be stored. The directory tree structure will mimic the tensordict’s. If
prefixends with".tdz"(orarchive=Trueis passed), a single-file archive is written instead of a directory: a standard zip file whose entries replicate the memmap directory layout. Seearchivebelow.copy_existing (bool) – If False (default), an exception will be raised if an entry in the tensordict is already a tensor stored on disk with an associated file, but is not saved in the correct location according to prefix. If
True, any existing Tensor will be copied to the new location.
- Keyword Arguments:
num_threads (int, optional) – the number of threads used to write the memmap tensors. Defaults to 0.
return_early (bool, optional) – if
Trueandnum_threads>0, the method will return a future of the tensordict.share_non_tensor (bool, optional) – if
True, the non-tensor data will be shared between the processes and writing operation (such as inplace update or set) on any of the workers within a single node will update the value on all other workers. If the number of non_tensor leaves is high (e.g., sharing large stacks of non-tensor data) this may result in OOM or similar errors. Defaults toFalse.existsok (bool, optional) – if
False, an exception will be raised if a tensor already exists in the same path. Defaults toTrue.robust_key (bool, optional) – if
True(default), uses robust key encoding that safely handles keys with path separators and special characters. IfFalse, uses legacy behavior (keys used as-is). IfNone, uses the default robust behavior.archive (bool, optional) – if
True,prefixdesignates a single file rather than a directory and the tensordict is written as a memmap archive: a zip file mirroring the memmap directory tree, with tensor payloads stored uncompressed and aligned so thatload_memmap()can memory-map the file and expose every leaf as a zero-copy view. IfNone(default), archive mode is enabled whenprefixends with".tdz". The result ofload_memmap()on an archive behaves like the result offrom_consolidated(): all leaves are views into a single storage, and in-place writes do not propagate to the file. Archives and memmap directories are mutually convertible withpack_memmap()/unpack_memmap()(or any zip tool). Note that archives are written sequentially (single data pass) andnum_threadshas no effect on them.compression (str or int, optional) – compression for archive entries (
"stored","deflate","bzip2","lzma"or azipfileconstant). Defaults to"stored"(uncompressed), which is what enables zero-copy loading. Compressed archives load correctly but leaves are decompressed in memory on access. Only valid in archive mode.
The TensorDict is then locked, meaning that any writing operations that isn’t in-place will throw an exception (eg, rename, set or remove an entry). Once the tensordict is unlocked, the memory-mapped attribute is turned to
False, because cross-process identity is not guaranteed anymore.- Returns:
A new tensordict with the tensors stored on disk if
return_early=False, otherwise aTensorDictFutureinstance.
Note
Serialising in this fashion might be slow with deeply nested tensordicts, so it is not recommended to call this method inside a training loop.
- memmap_(
- prefix: str | None = None,
- copy_existing: bool = False,
- *,
- num_threads: int = 0,
- return_early: bool = False,
- share_non_tensor: bool = False,
- existsok: bool = True,
- robust_key: bool | None = True,
Writes all tensors onto a corresponding memory-mapped Tensor, in-place.
- Parameters:
prefix (str) – directory prefix where the memory-mapped tensors will be stored. The directory tree structure will mimic the tensordict’s.
copy_existing (bool) – If False (default), an exception will be raised if an entry in the tensordict is already a tensor stored on disk with an associated file, but is not saved in the correct location according to prefix. If
True, any existing Tensor will be copied to the new location.
- Keyword Arguments:
num_threads (int, optional) – the number of threads used to write the memmap tensors. Defaults to 0.
return_early (bool, optional) – if
Trueandnum_threads>0, the method will return a future of the tensordict. The resulting tensordict can be queried using future.result().share_non_tensor (bool, optional) – if
True, the non-tensor data will be shared between the processes and writing operation (such as inplace update or set) on any of the workers within a single node will update the value on all other workers. If the number of non-tensor leaves is high (e.g., sharing large stacks of non-tensor data) this may result in OOM or similar errors. Defaults toFalse.existsok (bool, optional) – if
False, an exception will be raised if a tensor already exists in the same path. Defaults toTrue.robust_key (bool, optional) – if
True(default), uses robust key encoding that safely handles keys with path separators and special characters. IfFalse, uses legacy behavior (keys used as-is). IfNone, uses the default robust behavior.
The TensorDict is then locked, meaning that any writing operations that isn’t in-place will throw an exception (eg, rename, set or remove an entry). Once the tensordict is unlocked, the memory-mapped attribute is turned to
False, because cross-process identity is not guaranteed anymore.- Returns:
self if
return_early=False, otherwise aTensorDictFutureinstance.
Note
Serialising in this fashion might be slow with deeply nested tensordicts, so it is not recommended to call this method inside a training loop.
- memmap_like(
- prefix: str | None = None,
- copy_existing: bool = False,
- *,
- existsok: bool = True,
- num_threads: int = 0,
- return_early: bool = False,
- share_non_tensor: bool = False,
- robust_key: bool | None = True,
- archive: bool | None = None,
Creates a contentless Memory-mapped tensordict with the same shapes as the original one.
- Parameters:
prefix (str) – directory prefix where the memory-mapped tensors will be stored. The directory tree structure will mimic the tensordict’s. If
prefixends with".tdz"(orarchive=Trueis passed), a preallocated single-file archive is created instead. Seearchivebelow.copy_existing (bool) – If False (default), an exception will be raised if an entry in the tensordict is already a tensor stored on disk with an associated file, but is not saved in the correct location according to prefix. If
True, any existing Tensor will be copied to the new location.
- Keyword Arguments:
num_threads (int, optional) – the number of threads used to write the memmap tensors. Defaults to 0.
return_early (bool, optional) – if
Trueandnum_threads>0, the method will return a future of the tensordict.share_non_tensor (bool, optional) – if
True, the non-tensor data will be shared between the processes and writing operation (such as inplace update or set) on any of the workers within a single node will update the value on all other workers. If the number of non-tensor leaves is high (e.g., sharing large stacks of non-tensor data) this may result in OOM or similar errors. Defaults toFalse.existsok (bool, optional) – if
False, an exception will be raised if a tensor already exists in the same path. Defaults toTrue.robust_key (bool, optional) – if
True(default), uses robust key encoding that safely handles keys with path separators and special characters. IfFalse, uses legacy behavior (keys used as-is). IfNone, uses the default robust behavior.archive (bool, optional) – if
True,prefixdesignates a single file and a preallocated, zero-filled memmap archive is created and loaded back withload_memmap(prefix, mode="r+"): the returned tensordict writes through to the archive. IfNone(default), archive mode is enabled whenprefixends with".tdz". In-place writes leave the zip per-entry checksums stale; callrefresh_archive_checksums()before handing the archive to tools that verify them. Nested tensors are not supported in this mode.
The TensorDict is then locked, meaning that any writing operations that isn’t in-place will throw an exception (eg, rename, set or remove an entry). Once the tensordict is unlocked, the memory-mapped attribute is turned to
False, because cross-process identity is not guaranteed anymore.- Returns:
A new
TensorDictinstance with data stored as memory-mapped tensors ifreturn_early=False, otherwise aTensorDictFutureinstance.
Note
This is the recommended method to write a set of large buffers on disk, as
memmap_()will copy the information, which can be slow for large content.Examples
>>> td = TensorDict({ ... "a": torch.zeros((3, 64, 64), dtype=torch.uint8), ... "b": torch.zeros(1, dtype=torch.int64), ... }, batch_size=[]).expand(1_000_000) # expand does not allocate new memory >>> buffer = td.memmap_like("/path/to/dataset")
- memmap_refresh_(*, allow_pickle: bool | None = None)#
Refreshes the content of the memory-mapped tensordict if it has a
saved_path.This method will raise an exception if no path is associated with it.
- Parameters:
allow_pickle (bool, optional) – whether pickled non-tensor fields may be loaded. See
load_memmap().
- property n_nodes: int#
Number of nodes in the BVH.
- property n_spatial_dims: int#
Dimensionality of the spatial space.
- point_in_aabb(
- points: Float[Tensor, 'n_points n_spatial_dims'],
- aabb_min: Float[Tensor, 'n_boxes n_spatial_dims'],
- aabb_max: Float[Tensor, 'n_boxes n_spatial_dims'],
Test if points are inside axis-aligned bounding boxes.
- Parameters:
points (torch.Tensor) – Query points, shape
(n_points, n_spatial_dims).aabb_min (torch.Tensor) – Minimum corners, shape
(n_boxes, n_spatial_dims).aabb_max (torch.Tensor) – Maximum corners, shape
(n_boxes, n_spatial_dims).
- Returns:
Boolean tensor of shape
(n_points, n_boxes)indicating containment.- Return type:
torch.Tensor
- save(
- prefix: str | None = None,
- copy_existing: bool = False,
- *,
- num_threads: int = 0,
- return_early: bool = False,
- share_non_tensor: bool = False,
- robust_key: bool | None = True,
- archive: bool | None = None,
- compression: str | int | None = None,
Saves the tensordict to disk.
This function is a proxy to
memmap().
- select(
- *keys,
- inplace: bool = False,
- strict: bool = True,
- as_tensordict: bool = False,
TensorClass-specific select that supports
as_tensordict.
- set(
- key: NestedKey,
- value: Any,
- inplace: bool = False,
- non_blocking: bool = False,
Sets a new key-value pair.
- Parameters:
key (str, tuple of str) – name of the key to be set. If tuple of str it is equivalent to chained calls of getattr followed by a final setattr.
value (Any) – value to be stored in the tensorclass
inplace (bool, optional) – if
True, set will tentatively try to update the value in-place. IfFalseor if the key isn’t present, the value will be simply written at its destination.
- Returns:
self
- state_dict(
- destination=None,
- prefix='',
- keep_vars=False,
- flatten=True,
Returns a state_dict with logical keys, matching TensorDictBase conventions.
Tensor fields appear as data keys. Non-tensor fields (strings, ints, etc.) and the tensorclass type are stored in
_metadata. This replaces the legacy_tensordict/_non_tensordictwrapper format.
- to_tensordict(
- *,
- retain_none: bool | None = None,
Convert the tensorclass into a regular TensorDict.
Makes a copy of all entries. Memmap and shared memory tensors are converted to regular tensors.
- Parameters:
retain_none (bool) – if
True, theNonevalues will be written in the tensordict. Otherwise they will be discrarded. Default:True.- Returns:
A new TensorDict object containing the same values as the tensorclass.
- unbind(dim: int)#
Returns a tuple of indexed tensorclass instances unbound along the indicated dimension.
Resulting tensorclass instances will share the storage of the initial tensorclass instance.
- class physicsnemo.mesh.spatial.ClusterTree(
- node_aabb_min: torch.Tensor,
- node_aabb_max: torch.Tensor,
- node_diameter_sq: torch.Tensor,
- node_left_child: torch.Tensor,
- node_right_child: torch.Tensor,
- leaf_start: torch.Tensor,
- leaf_count: torch.Tensor,
- node_range_start: torch.Tensor,
- node_range_count: torch.Tensor,
- node_total_area: torch.Tensor,
- sorted_source_order: torch.Tensor,
- source_points: torch.Tensor,
- max_depth: torch.Tensor,
- *,
- batch_size,
- device=None,
- names=None,
Bases:
object- compute_source_aggregates(
- source_points: Float[Tensor, 'n_sources n_dims'],
- areas: Float[Tensor, 'n_sources'],
- source_data: TensorDict | None = None,
Compute per-node aggregate source data for far-field approximation.
Aggregates are area-weighted averages of source features within each node’s subtree. The
areaspassed to this call are authoritative for both the weighted sums and their normalization; they need not match the areas used to construct the tree. Per-source strengths are handled separately during kernel evaluation.- Parameters:
source_points (Float[torch.Tensor, "n_sources n_dims"]) – Source coordinates, shape \((N, D)\).
areas (Float[torch.Tensor, "n_sources"]) – Per-source area weights, shape \((N,)\).
source_data (TensorDict or None) – Per-source features (normals, latents, etc.) with
batch_size=(N,).Noneif no per-source features.
- Returns:
Per-node aggregated centroids and source data.
- Return type:
Notes
Tree topology depends on point positions, so callers may reuse a cached tree with different aggregation weights.
node_total_arearemains construction-time metadata; it is not the normalization for this call’s aggregates.
- property device: device#
Retrieves the device type of tensor class.
- dumps(
- prefix: str | None = None,
- copy_existing: bool = False,
- *,
- num_threads: int = 0,
- return_early: bool = False,
- share_non_tensor: bool = False,
- robust_key: bool | None = True,
- archive: bool | None = None,
- compression: str | int | None = None,
Saves the tensordict to disk.
This function is a proxy to
memmap().
- classmethod fields()#
Return a tuple describing the fields of this dataclass.
Accepts a dataclass or an instance of one. Tuple elements are of type Field.
- find_dual_interaction_pairs(
- target_tree: ClusterTree,
- theta: float = 1.0,
- *,
- expand_far_targets: bool = False,
Find near-field and far-field pairs via dual-tree traversal.
Traverses both the source tree (
self) andtarget_treesimultaneously. For well-separated node pairs, records a single far-field (target_node, source_node) entry - the kernel is evaluated ONCE at the node centroids and broadcast to all targets in the node. This reduces far-field kernel evaluations from O(N log N) to O(N).Uses a combined AABB-distance opening criterion:
(D_T + D_S) / r < theta, where D_T and D_S are the AABB diagonals and r is the minimum distance between the two AABBs. This accounts for approximation error on both the target and source sides.- Parameters:
target_tree (ClusterTree) – Tree over target points. For self-interaction (communication layers), this is the same object as
self.theta (float) – Barnes-Hut opening angle. Larger = more aggressive.
theta = 0forces all interactions to be exact.expand_far_targets (bool, optional, default=False) – If
True, far-field node pairs are expanded to individual target points, converting(far, far)entries into(near, far)entries. This eliminates the target-side centroid approximation (and the blocky spatial artifacts it produces) at the cost of more kernel evaluations while preserving the source-side monopole speedup.
- Returns:
Near-field individual pairs and far-field node-to-node pairs.
- Return type:
- from_csv(
- *,
- auto_batch_size: bool = False,
- batch_dims: int | None = None,
- device: device | None = None,
- batch_size: Size | None = None,
- separator: str | None = None,
- dtype: dtype | None = None,
- **kwargs,
Creates a TensorDict from a CSV file.
Requires either pandas or pyarrow to be installed.
- Parameters:
path (str or Path) – Path to the CSV file.
- Keyword Arguments:
auto_batch_size (bool, optional) – If
True, the batch size will be computed automatically. Defaults toFalse.batch_dims (int, optional) – If
auto_batch_sizeisTrue, defines how many dimensions the output tensordict should have. Defaults toNone.device (torch.device, optional) – The device for tensor data. Defaults to
None.batch_size (torch.Size, optional) – The batch size. Defaults to
[num_rows].separator (str, optional) – If provided, column names are split on this separator to create nested TensorDicts. Defaults to
None.dtype (torch.dtype, optional) – If provided, all numeric columns are cast to this dtype. Defaults to
None.**kwargs – Additional keyword arguments forwarded to the CSV reader (
pandas.read_csvorpyarrow.csv.read_csv).
- Returns:
A TensorDict representation of the CSV data.
Examples
>>> td = TensorDict.from_csv("data.csv") >>> td = TensorDict.from_csv("data.csv", separator=".", dtype=torch.float32)
- from_json(
- *,
- auto_batch_size: bool = False,
- batch_dims: int | None = None,
- device: device | None = None,
- batch_size: Size | None = None,
- separator: str | None = None,
- dtype: dtype | None = None,
- lines: bool = False,
- **kwargs,
Creates a TensorDict from a JSON file.
Supports both standard JSON (array of records) and JSON Lines format. For nested JSON objects, use
from_dict()instead.Requires pandas for best results. Falls back to stdlib
jsonfor simple cases.- Parameters:
path (str or Path) – Path to the JSON file.
- Keyword Arguments:
auto_batch_size (bool, optional) – If
True, the batch size will be computed automatically. Defaults toFalse.batch_dims (int, optional) – If
auto_batch_sizeisTrue, defines how many dimensions the output tensordict should have. Defaults toNone.device (torch.device, optional) – The device for tensor data. Defaults to
None.batch_size (torch.Size, optional) – The batch size. Defaults to
[num_rows].separator (str, optional) – If provided, column names are split on this separator to create nested TensorDicts. Defaults to
None.dtype (torch.dtype, optional) – If provided, all numeric columns are cast to this dtype. Defaults to
None.lines (bool, optional) – If
True, reads the file as JSON Lines (one JSON object per line). Defaults toFalse.**kwargs – Additional keyword arguments forwarded to the JSON reader.
- Returns:
A TensorDict representation of the JSON data.
Examples
>>> td = TensorDict.from_json("data.json") >>> td = TensorDict.from_json("data.jsonl", lines=True)
- from_pandas(
- *,
- auto_batch_size: bool = False,
- batch_dims: int | None = None,
- device: device | None = None,
- batch_size: Size | None = None,
- separator: str | None = None,
- dtype: dtype | None = None,
Converts a pandas DataFrame to a TensorDict.
Numeric columns become tensors, string/object columns become
NonTensorData.- Parameters:
dataframe (pd.DataFrame) – The pandas DataFrame to convert.
- Keyword Arguments:
auto_batch_size (bool, optional) – If
True, the batch size will be computed automatically. Defaults toFalse.batch_dims (int, optional) – If
auto_batch_sizeisTrue, defines how many dimensions the output tensordict should have. Defaults toNone.device (torch.device, optional) – The device for tensor data. Defaults to
None.batch_size (torch.Size, optional) – The batch size. Defaults to
[num_rows].separator (str, optional) – If provided, column names are split on this separator to create nested TensorDicts. For example, with
separator=".", a column"obs.x"becomestd["obs", "x"]. Defaults toNone.dtype (torch.dtype, optional) – If provided, all numeric columns are cast to this dtype. Defaults to
None.
- Returns:
A TensorDict representation of the DataFrame.
Examples
>>> import pandas as pd >>> df = pd.DataFrame({"a": [1, 2, 3], "b": [4.0, 5.0, 6.0]}) >>> td = TensorDict.from_pandas(df) >>> print(td) TensorDict( fields={ a: Tensor(shape=torch.Size([3]), device=cpu, dtype=torch.int64, is_shared=False), b: Tensor(shape=torch.Size([3]), device=cpu, dtype=torch.float64, is_shared=False)}, batch_size=torch.Size([3]), device=None, is_shared=False)
- from_parquet(
- *,
- auto_batch_size: bool = False,
- batch_dims: int | None = None,
- device: device | None = None,
- batch_size: Size | None = None,
- separator: str | None = None,
- dtype: dtype | None = None,
- columns: list[str] | None = None,
- **kwargs,
Creates a TensorDict from a Parquet file.
Requires either pyarrow or pandas to be installed. Prefers pyarrow when available for better performance.
- Parameters:
path (str or Path) – Path to the Parquet file.
- Keyword Arguments:
auto_batch_size (bool, optional) – If
True, the batch size will be computed automatically. Defaults toFalse.batch_dims (int, optional) – If
auto_batch_sizeisTrue, defines how many dimensions the output tensordict should have. Defaults toNone.device (torch.device, optional) – The device for tensor data. Defaults to
None.batch_size (torch.Size, optional) – The batch size. Defaults to
[num_rows].separator (str, optional) – If provided, column names are split on this separator to create nested TensorDicts. Defaults to
None.dtype (torch.dtype, optional) – If provided, all numeric columns are cast to this dtype. Defaults to
None.columns (list of str, optional) – If provided, only read these columns from the file. Defaults to
None(all columns).**kwargs – Additional keyword arguments forwarded to the Parquet reader.
- Returns:
A TensorDict representation of the Parquet data.
Examples
>>> td = TensorDict.from_parquet("data.parquet") >>> td = TensorDict.from_parquet("data.parquet", columns=["obs", "reward"])
- classmethod from_points(
- points: Float[Tensor, 'n_points n_dims'],
- *,
- leaf_size: int = 1,
- areas: Float[Tensor, 'n_points'] | None = None,
Build a cluster tree from a set of points via morton-code LBVH.
- Parameters:
points (Float[torch.Tensor, "n_points n_dims"]) – Source point coordinates, shape \((N, D)\).
leaf_size (int) – Maximum sources per leaf node. Larger values produce shallower trees (fewer traversal iterations) at the cost of more exact near-field interactions per leaf hit.
areas (Float[torch.Tensor, "n_points"] or None) – Per-source area weights used for aggregate computation. If
None, all areas default to 1.
- Returns:
Constructed tree ready for traversal and aggregate computation.
- Return type:
- from_schema(
- *,
- batch_size: Sequence[int] | Size | None = None,
- storage: str | None = None,
- device=None,
- **kwargs,
Pre-allocate a zero-filled TensorDict from a schema.
Creates a
TensorDictBasewhose storage backend is selected bystorage. Each entry inschemamaps a field name to an(element_shape, dtype)pair; the full stored shape is[*batch_size, *element_shape].- Parameters:
schema – Mapping from field name to
(element_shape, dtype).element_shapeis the per-element shape (excludingbatch_size).- Keyword Arguments:
batch_size – Overall batch dimensions prepended to every element shape. Defaults to
().storage (str or None) –
Backend selector:
None– plainTensorDictwith regular tensors."memmap"– memory-mapped tensors on disk. Passprefix=<dir>in kwargs."h5"– HDF5 viaPersistentTensorDict. Passfilename=<path>in kwargs."zarr"– zarr (requireszarr>=3.0) viaPersistentTensorDict. Passfilename=<path or store>in kwargs."shared"– CPU shared-memory tensors."redis"/"dragonfly"– delegates toTensorDictStore.from_schema().
device – Device for the resulting tensors (ignored by some backends).
**kwargs – Backend-specific arguments forwarded to the underlying constructor (e.g.
prefixfor memmap,filenamefor h5,host/portfor redis).
- Returns:
A new
TensorDictBasesubclass instance with pre-allocated (zero-filled) keys.
Examples
>>> td = TensorDict.from_schema( ... {"obs": ([84, 84, 3], torch.uint8), ... "reward": ([], torch.float32)}, ... batch_size=[1000], ... ) >>> td["obs"].shape torch.Size([1000, 84, 84, 3])
>>> import tempfile >>> with tempfile.TemporaryDirectory() as d: ... td_mm = TensorDict.from_schema( ... {"obs": ([4], torch.float32)}, ... batch_size=[8], ... storage="memmap", ... prefix=d, ... ) ... assert td_mm.is_memmap()
- classmethod from_tensordict(
- tensordict: TensorDictBase,
- non_tensordict: dict | None = None,
- safe: bool = True,
Tensor class wrapper to instantiate a new tensor class object.
- Parameters:
tensordict (TensorDictBase) – Dictionary of tensor types
non_tensordict (dict) – Dictionary with non-tensor and nested tensor class objects
safe (bool) – Whether to raise an error if the tensordict is not a TensorDictBase instance
- get(
- key: NestedKey,
- *args,
- **kwargs,
Gets the value stored with the input key.
- Parameters:
key (str, tuple of str) – key to be queried. If tuple of str it is equivalent to chained calls of getattr.
default – default value if the key is not found in the tensorclass.
- Returns:
value stored with the input key
- classmethod load(
- prefix: str | Path,
- *args,
- **kwargs,
Loads a tensordict from disk.
This class method is a proxy to
load_memmap().
- load_(prefix: str | Path, *args, **kwargs)#
Loads a tensordict from disk within the current tensordict.
This class method is a proxy to
load_memmap_().
- classmethod load_memmap(
- prefix: str | Path,
- device: device | None = None,
- non_blocking: bool = False,
- *,
- out: TensorDictBase | None = None,
- robust_key: bool | None = True,
- subpath: NestedKey | None = None,
- mode: str = 'r',
- num_threads: int = 0,
- allow_pickle: bool | None = None,
Loads a memory-mapped tensordict from disk.
- Parameters:
prefix (str or Path to folder) – the path to the folder where the saved tensordict should be fetched, or the path to a memmap archive file written through
save(..., archive=True)/ a".tdz"prefix (or packed withpack_memmap()). Archives are memory-mapped once and every leaf is exposed as a zero-copy view into the mapping: only the pages of the leaves that are actually accessed are read from disk. Unlike directory-backed tensordicts, in-place writes to the leaves of an archive-loaded tensordict do not propagate to the file.device (torch.device or equivalent, optional) – if provided, the data will be asynchronously cast to that device. Supports “meta” device, in which case the data isn’t loaded but a set of empty “meta” tensors are created. This is useful to get a sense of the total model size and structure without actually opening any file.
non_blocking (bool, optional) – if
True, synchronize won’t be called after loading tensors on device. Defaults toFalse.out (TensorDictBase, optional) – optional tensordict where the data should be written.
robust_key (bool, optional) – if
True(default), expects robust key encoding was used when saving and decodes filenames accordingly. IfFalse, uses legacy behavior. IfNone, uses the default robust behavior.subpath (NestedKey or str path, optional) – the location of a nested tensordict to load, as a nested key (e.g.
("module", "0"), with arbitrary nesting allowed as usual) or as a"/"-separated string path (e.g."module/0"). Only that subtree is loaded. Works both for directories (equivalent to appending the path toprefix) and for archives.mode (str, optional) –
"r"(default) or"r+". Only relevant when loading an archive: with"r"the archive is mapped copy-on-write and in-place writes to the leaves stay in memory; with"r+"the mapping is shared and in-place writes propagate to the file, like directory-backed tensordicts."r+"requires uncompressed, aligned tensor payloads (i.e. archives written by tensordict withoutcompression) and is not available for nested-tensor leaves. In-place writes do not update the per-entry CRC-32 stored by the zip format;load_memmap()ignores checksums, but callrefresh_archive_checksums()before handing a modified archive to tools that verify them (unzip,unpack_memmap(), …). Directory prefixes are always write-through and ignore this argument.num_threads (int, optional) – number of threads used to decompress the leaves of a compressed archive (deflate entries are inflated in parallel, which scales nearly linearly). Without compression, loading is a metadata-only operation and this argument has no effect. Defaults to
0(sequential).allow_pickle (bool, optional) – whether pickled non-tensor fields may be loaded. Pickle can execute arbitrary code, so pass
Trueonly for data from a trusted source andFalsefor untrusted data. During the 0.14 compatibility window, omitting this option loads pickle with aFutureWarning; the default will change toFalsein 0.15. Saves without a pickle sidecar do not require this option.
Examples
>>> from tensordict import TensorDict >>> td = TensorDict.fromkeys(["a", "b", "c", ("nested", "e")], 0) >>> td.memmap("./saved_td") >>> td_load = TensorDict.load_memmap("./saved_td") >>> assert (td == td_load).all()
This method also allows loading nested tensordicts.
Examples
>>> nested = TensorDict.load_memmap("./saved_td/nested") >>> assert nested["e"] == 0
A tensordict can also be loaded on “meta” device or, alternatively, as a fake tensor.
Examples
>>> import tempfile >>> td = TensorDict({"a": torch.zeros(()), "b": {"c": torch.zeros(())}}) >>> with tempfile.TemporaryDirectory() as path: ... td.save(path) ... td_load = TensorDict.load_memmap(path, device="meta") ... print("meta:", td_load) ... from torch._subclasses import FakeTensorMode ... with FakeTensorMode(): ... td_load = TensorDict.load_memmap(path) ... print("fake:", td_load) meta: TensorDict( fields={ a: Tensor(shape=torch.Size([]), device=meta, dtype=torch.float32, is_shared=False), b: TensorDict( fields={ c: Tensor(shape=torch.Size([]), device=meta, dtype=torch.float32, is_shared=False)}, batch_size=torch.Size([]), device=meta, is_shared=False)}, batch_size=torch.Size([]), device=meta, is_shared=False) fake: TensorDict( fields={ a: FakeTensor(shape=torch.Size([]), device=cpu, dtype=torch.float32, is_shared=False), b: TensorDict( fields={ c: FakeTensor(shape=torch.Size([]), device=cpu, dtype=torch.float32, is_shared=False)}, batch_size=torch.Size([]), device=cpu, is_shared=False)}, batch_size=torch.Size([]), device=cpu, is_shared=False)
- load_state_dict(
- state_dict: dict[str, Any],
- strict=True,
- assign=False,
- from_flatten=None,
Loads a state_dict into the tensorclass.
Supports both the new format (logical keys with
_metadata) and the legacy format (_tensordict/_non_tensordictwrapper keys).
- memmap(
- prefix: str | None = None,
- copy_existing: bool = False,
- *,
- num_threads: int = 0,
- return_early: bool = False,
- share_non_tensor: bool = False,
- existsok: bool = True,
- robust_key: bool | None = True,
- archive: bool | None = None,
- compression: str | int | None = None,
Writes all tensors onto a corresponding memory-mapped Tensor in a new tensordict.
- Parameters:
prefix (str) – directory prefix where the memory-mapped tensors will be stored. The directory tree structure will mimic the tensordict’s. If
prefixends with".tdz"(orarchive=Trueis passed), a single-file archive is written instead of a directory: a standard zip file whose entries replicate the memmap directory layout. Seearchivebelow.copy_existing (bool) – If False (default), an exception will be raised if an entry in the tensordict is already a tensor stored on disk with an associated file, but is not saved in the correct location according to prefix. If
True, any existing Tensor will be copied to the new location.
- Keyword Arguments:
num_threads (int, optional) – the number of threads used to write the memmap tensors. Defaults to 0.
return_early (bool, optional) – if
Trueandnum_threads>0, the method will return a future of the tensordict.share_non_tensor (bool, optional) – if
True, the non-tensor data will be shared between the processes and writing operation (such as inplace update or set) on any of the workers within a single node will update the value on all other workers. If the number of non_tensor leaves is high (e.g., sharing large stacks of non-tensor data) this may result in OOM or similar errors. Defaults toFalse.existsok (bool, optional) – if
False, an exception will be raised if a tensor already exists in the same path. Defaults toTrue.robust_key (bool, optional) – if
True(default), uses robust key encoding that safely handles keys with path separators and special characters. IfFalse, uses legacy behavior (keys used as-is). IfNone, uses the default robust behavior.archive (bool, optional) – if
True,prefixdesignates a single file rather than a directory and the tensordict is written as a memmap archive: a zip file mirroring the memmap directory tree, with tensor payloads stored uncompressed and aligned so thatload_memmap()can memory-map the file and expose every leaf as a zero-copy view. IfNone(default), archive mode is enabled whenprefixends with".tdz". The result ofload_memmap()on an archive behaves like the result offrom_consolidated(): all leaves are views into a single storage, and in-place writes do not propagate to the file. Archives and memmap directories are mutually convertible withpack_memmap()/unpack_memmap()(or any zip tool). Note that archives are written sequentially (single data pass) andnum_threadshas no effect on them.compression (str or int, optional) – compression for archive entries (
"stored","deflate","bzip2","lzma"or azipfileconstant). Defaults to"stored"(uncompressed), which is what enables zero-copy loading. Compressed archives load correctly but leaves are decompressed in memory on access. Only valid in archive mode.
The TensorDict is then locked, meaning that any writing operations that isn’t in-place will throw an exception (eg, rename, set or remove an entry). Once the tensordict is unlocked, the memory-mapped attribute is turned to
False, because cross-process identity is not guaranteed anymore.- Returns:
A new tensordict with the tensors stored on disk if
return_early=False, otherwise aTensorDictFutureinstance.
Note
Serialising in this fashion might be slow with deeply nested tensordicts, so it is not recommended to call this method inside a training loop.
- memmap_(
- prefix: str | None = None,
- copy_existing: bool = False,
- *,
- num_threads: int = 0,
- return_early: bool = False,
- share_non_tensor: bool = False,
- existsok: bool = True,
- robust_key: bool | None = True,
Writes all tensors onto a corresponding memory-mapped Tensor, in-place.
- Parameters:
prefix (str) – directory prefix where the memory-mapped tensors will be stored. The directory tree structure will mimic the tensordict’s.
copy_existing (bool) – If False (default), an exception will be raised if an entry in the tensordict is already a tensor stored on disk with an associated file, but is not saved in the correct location according to prefix. If
True, any existing Tensor will be copied to the new location.
- Keyword Arguments:
num_threads (int, optional) – the number of threads used to write the memmap tensors. Defaults to 0.
return_early (bool, optional) – if
Trueandnum_threads>0, the method will return a future of the tensordict. The resulting tensordict can be queried using future.result().share_non_tensor (bool, optional) – if
True, the non-tensor data will be shared between the processes and writing operation (such as inplace update or set) on any of the workers within a single node will update the value on all other workers. If the number of non-tensor leaves is high (e.g., sharing large stacks of non-tensor data) this may result in OOM or similar errors. Defaults toFalse.existsok (bool, optional) – if
False, an exception will be raised if a tensor already exists in the same path. Defaults toTrue.robust_key (bool, optional) – if
True(default), uses robust key encoding that safely handles keys with path separators and special characters. IfFalse, uses legacy behavior (keys used as-is). IfNone, uses the default robust behavior.
The TensorDict is then locked, meaning that any writing operations that isn’t in-place will throw an exception (eg, rename, set or remove an entry). Once the tensordict is unlocked, the memory-mapped attribute is turned to
False, because cross-process identity is not guaranteed anymore.- Returns:
self if
return_early=False, otherwise aTensorDictFutureinstance.
Note
Serialising in this fashion might be slow with deeply nested tensordicts, so it is not recommended to call this method inside a training loop.
- memmap_like(
- prefix: str | None = None,
- copy_existing: bool = False,
- *,
- existsok: bool = True,
- num_threads: int = 0,
- return_early: bool = False,
- share_non_tensor: bool = False,
- robust_key: bool | None = True,
- archive: bool | None = None,
Creates a contentless Memory-mapped tensordict with the same shapes as the original one.
- Parameters:
prefix (str) – directory prefix where the memory-mapped tensors will be stored. The directory tree structure will mimic the tensordict’s. If
prefixends with".tdz"(orarchive=Trueis passed), a preallocated single-file archive is created instead. Seearchivebelow.copy_existing (bool) – If False (default), an exception will be raised if an entry in the tensordict is already a tensor stored on disk with an associated file, but is not saved in the correct location according to prefix. If
True, any existing Tensor will be copied to the new location.
- Keyword Arguments:
num_threads (int, optional) – the number of threads used to write the memmap tensors. Defaults to 0.
return_early (bool, optional) – if
Trueandnum_threads>0, the method will return a future of the tensordict.share_non_tensor (bool, optional) – if
True, the non-tensor data will be shared between the processes and writing operation (such as inplace update or set) on any of the workers within a single node will update the value on all other workers. If the number of non-tensor leaves is high (e.g., sharing large stacks of non-tensor data) this may result in OOM or similar errors. Defaults toFalse.existsok (bool, optional) – if
False, an exception will be raised if a tensor already exists in the same path. Defaults toTrue.robust_key (bool, optional) – if
True(default), uses robust key encoding that safely handles keys with path separators and special characters. IfFalse, uses legacy behavior (keys used as-is). IfNone, uses the default robust behavior.archive (bool, optional) – if
True,prefixdesignates a single file and a preallocated, zero-filled memmap archive is created and loaded back withload_memmap(prefix, mode="r+"): the returned tensordict writes through to the archive. IfNone(default), archive mode is enabled whenprefixends with".tdz". In-place writes leave the zip per-entry checksums stale; callrefresh_archive_checksums()before handing the archive to tools that verify them. Nested tensors are not supported in this mode.
The TensorDict is then locked, meaning that any writing operations that isn’t in-place will throw an exception (eg, rename, set or remove an entry). Once the tensordict is unlocked, the memory-mapped attribute is turned to
False, because cross-process identity is not guaranteed anymore.- Returns:
A new
TensorDictinstance with data stored as memory-mapped tensors ifreturn_early=False, otherwise aTensorDictFutureinstance.
Note
This is the recommended method to write a set of large buffers on disk, as
memmap_()will copy the information, which can be slow for large content.Examples
>>> td = TensorDict({ ... "a": torch.zeros((3, 64, 64), dtype=torch.uint8), ... "b": torch.zeros(1, dtype=torch.int64), ... }, batch_size=[]).expand(1_000_000) # expand does not allocate new memory >>> buffer = td.memmap_like("/path/to/dataset")
- memmap_refresh_(*, allow_pickle: bool | None = None)#
Refreshes the content of the memory-mapped tensordict if it has a
saved_path.This method will raise an exception if no path is associated with it.
- Parameters:
allow_pickle (bool, optional) – whether pickled non-tensor fields may be loaded. See
load_memmap().
- property n_nodes: int#
Number of nodes in the tree.
- property n_sources: int#
Number of source points.
- property n_spatial_dims: int#
Spatial dimensionality.
- save(
- prefix: str | None = None,
- copy_existing: bool = False,
- *,
- num_threads: int = 0,
- return_early: bool = False,
- share_non_tensor: bool = False,
- robust_key: bool | None = True,
- archive: bool | None = None,
- compression: str | int | None = None,
Saves the tensordict to disk.
This function is a proxy to
memmap().
- select(
- *keys,
- inplace: bool = False,
- strict: bool = True,
- as_tensordict: bool = False,
TensorClass-specific select that supports
as_tensordict.
- set(
- key: NestedKey,
- value: Any,
- inplace: bool = False,
- non_blocking: bool = False,
Sets a new key-value pair.
- Parameters:
key (str, tuple of str) – name of the key to be set. If tuple of str it is equivalent to chained calls of getattr followed by a final setattr.
value (Any) – value to be stored in the tensorclass
inplace (bool, optional) – if
True, set will tentatively try to update the value in-place. IfFalseor if the key isn’t present, the value will be simply written at its destination.
- Returns:
self
- state_dict(
- destination=None,
- prefix='',
- keep_vars=False,
- flatten=True,
Returns a state_dict with logical keys, matching TensorDictBase conventions.
Tensor fields appear as data keys. Non-tensor fields (strings, ints, etc.) and the tensorclass type are stored in
_metadata. This replaces the legacy_tensordict/_non_tensordictwrapper format.
- to_tensordict(
- *,
- retain_none: bool | None = None,
Convert the tensorclass into a regular TensorDict.
Makes a copy of all entries. Memmap and shared memory tensors are converted to regular tensors.
- Parameters:
retain_none (bool) – if
True, theNonevalues will be written in the tensordict. Otherwise they will be discrarded. Default:True.- Returns:
A new TensorDict object containing the same values as the tensorclass.
- unbind(dim: int)#
Returns a tuple of indexed tensorclass instances unbound along the indicated dimension.
Resulting tensorclass instances will share the storage of the initial tensorclass instance.
- class physicsnemo.mesh.spatial.DualInteractionPlan(
- near_target_ids: jaxtyping.Int[Tensor, 'n_near'],
- near_source_ids: jaxtyping.Int[Tensor, 'n_near'],
- far_target_node_ids: jaxtyping.Int[Tensor, 'n_far_nodes'],
- far_source_node_ids: jaxtyping.Int[Tensor, 'n_far_nodes'],
- nf_target_ids: jaxtyping.Int[Tensor, 'n_nf'],
- nf_source_node_ids: jaxtyping.Int[Tensor, 'n_nf'],
- fn_target_node_ids: jaxtyping.Int[Tensor, 'n_fn'],
- fn_source_ids: jaxtyping.Int[Tensor, 'n_fn'],
- fn_broadcast_targets: jaxtyping.Int[Tensor, 'n_fn_bcast'],
- fn_broadcast_starts: jaxtyping.Int[Tensor, 'n_fn'],
- fn_broadcast_counts: jaxtyping.Int[Tensor, 'n_fn'],
- *,
- batch_size,
- device=None,
- names=None,
Bases:
object- property device: device#
Retrieves the device type of tensor class.
- dumps(
- prefix: str | None = None,
- copy_existing: bool = False,
- *,
- num_threads: int = 0,
- return_early: bool = False,
- share_non_tensor: bool = False,
- robust_key: bool | None = True,
- archive: bool | None = None,
- compression: str | int | None = None,
Saves the tensordict to disk.
This function is a proxy to
memmap().
- classmethod fields()#
Return a tuple describing the fields of this dataclass.
Accepts a dataclass or an instance of one. Tuple elements are of type Field.
- from_csv(
- *,
- auto_batch_size: bool = False,
- batch_dims: int | None = None,
- device: device | None = None,
- batch_size: Size | None = None,
- separator: str | None = None,
- dtype: dtype | None = None,
- **kwargs,
Creates a TensorDict from a CSV file.
Requires either pandas or pyarrow to be installed.
- Parameters:
path (str or Path) – Path to the CSV file.
- Keyword Arguments:
auto_batch_size (bool, optional) – If
True, the batch size will be computed automatically. Defaults toFalse.batch_dims (int, optional) – If
auto_batch_sizeisTrue, defines how many dimensions the output tensordict should have. Defaults toNone.device (torch.device, optional) – The device for tensor data. Defaults to
None.batch_size (torch.Size, optional) – The batch size. Defaults to
[num_rows].separator (str, optional) – If provided, column names are split on this separator to create nested TensorDicts. Defaults to
None.dtype (torch.dtype, optional) – If provided, all numeric columns are cast to this dtype. Defaults to
None.**kwargs – Additional keyword arguments forwarded to the CSV reader (
pandas.read_csvorpyarrow.csv.read_csv).
- Returns:
A TensorDict representation of the CSV data.
Examples
>>> td = TensorDict.from_csv("data.csv") >>> td = TensorDict.from_csv("data.csv", separator=".", dtype=torch.float32)
- from_json(
- *,
- auto_batch_size: bool = False,
- batch_dims: int | None = None,
- device: device | None = None,
- batch_size: Size | None = None,
- separator: str | None = None,
- dtype: dtype | None = None,
- lines: bool = False,
- **kwargs,
Creates a TensorDict from a JSON file.
Supports both standard JSON (array of records) and JSON Lines format. For nested JSON objects, use
from_dict()instead.Requires pandas for best results. Falls back to stdlib
jsonfor simple cases.- Parameters:
path (str or Path) – Path to the JSON file.
- Keyword Arguments:
auto_batch_size (bool, optional) – If
True, the batch size will be computed automatically. Defaults toFalse.batch_dims (int, optional) – If
auto_batch_sizeisTrue, defines how many dimensions the output tensordict should have. Defaults toNone.device (torch.device, optional) – The device for tensor data. Defaults to
None.batch_size (torch.Size, optional) – The batch size. Defaults to
[num_rows].separator (str, optional) – If provided, column names are split on this separator to create nested TensorDicts. Defaults to
None.dtype (torch.dtype, optional) – If provided, all numeric columns are cast to this dtype. Defaults to
None.lines (bool, optional) – If
True, reads the file as JSON Lines (one JSON object per line). Defaults toFalse.**kwargs – Additional keyword arguments forwarded to the JSON reader.
- Returns:
A TensorDict representation of the JSON data.
Examples
>>> td = TensorDict.from_json("data.json") >>> td = TensorDict.from_json("data.jsonl", lines=True)
- from_pandas(
- *,
- auto_batch_size: bool = False,
- batch_dims: int | None = None,
- device: device | None = None,
- batch_size: Size | None = None,
- separator: str | None = None,
- dtype: dtype | None = None,
Converts a pandas DataFrame to a TensorDict.
Numeric columns become tensors, string/object columns become
NonTensorData.- Parameters:
dataframe (pd.DataFrame) – The pandas DataFrame to convert.
- Keyword Arguments:
auto_batch_size (bool, optional) – If
True, the batch size will be computed automatically. Defaults toFalse.batch_dims (int, optional) – If
auto_batch_sizeisTrue, defines how many dimensions the output tensordict should have. Defaults toNone.device (torch.device, optional) – The device for tensor data. Defaults to
None.batch_size (torch.Size, optional) – The batch size. Defaults to
[num_rows].separator (str, optional) – If provided, column names are split on this separator to create nested TensorDicts. For example, with
separator=".", a column"obs.x"becomestd["obs", "x"]. Defaults toNone.dtype (torch.dtype, optional) – If provided, all numeric columns are cast to this dtype. Defaults to
None.
- Returns:
A TensorDict representation of the DataFrame.
Examples
>>> import pandas as pd >>> df = pd.DataFrame({"a": [1, 2, 3], "b": [4.0, 5.0, 6.0]}) >>> td = TensorDict.from_pandas(df) >>> print(td) TensorDict( fields={ a: Tensor(shape=torch.Size([3]), device=cpu, dtype=torch.int64, is_shared=False), b: Tensor(shape=torch.Size([3]), device=cpu, dtype=torch.float64, is_shared=False)}, batch_size=torch.Size([3]), device=None, is_shared=False)
- from_parquet(
- *,
- auto_batch_size: bool = False,
- batch_dims: int | None = None,
- device: device | None = None,
- batch_size: Size | None = None,
- separator: str | None = None,
- dtype: dtype | None = None,
- columns: list[str] | None = None,
- **kwargs,
Creates a TensorDict from a Parquet file.
Requires either pyarrow or pandas to be installed. Prefers pyarrow when available for better performance.
- Parameters:
path (str or Path) – Path to the Parquet file.
- Keyword Arguments:
auto_batch_size (bool, optional) – If
True, the batch size will be computed automatically. Defaults toFalse.batch_dims (int, optional) – If
auto_batch_sizeisTrue, defines how many dimensions the output tensordict should have. Defaults toNone.device (torch.device, optional) – The device for tensor data. Defaults to
None.batch_size (torch.Size, optional) – The batch size. Defaults to
[num_rows].separator (str, optional) – If provided, column names are split on this separator to create nested TensorDicts. Defaults to
None.dtype (torch.dtype, optional) – If provided, all numeric columns are cast to this dtype. Defaults to
None.columns (list of str, optional) – If provided, only read these columns from the file. Defaults to
None(all columns).**kwargs – Additional keyword arguments forwarded to the Parquet reader.
- Returns:
A TensorDict representation of the Parquet data.
Examples
>>> td = TensorDict.from_parquet("data.parquet") >>> td = TensorDict.from_parquet("data.parquet", columns=["obs", "reward"])
- from_schema(
- *,
- batch_size: Sequence[int] | Size | None = None,
- storage: str | None = None,
- device=None,
- **kwargs,
Pre-allocate a zero-filled TensorDict from a schema.
Creates a
TensorDictBasewhose storage backend is selected bystorage. Each entry inschemamaps a field name to an(element_shape, dtype)pair; the full stored shape is[*batch_size, *element_shape].- Parameters:
schema – Mapping from field name to
(element_shape, dtype).element_shapeis the per-element shape (excludingbatch_size).- Keyword Arguments:
batch_size – Overall batch dimensions prepended to every element shape. Defaults to
().storage (str or None) –
Backend selector:
None– plainTensorDictwith regular tensors."memmap"– memory-mapped tensors on disk. Passprefix=<dir>in kwargs."h5"– HDF5 viaPersistentTensorDict. Passfilename=<path>in kwargs."zarr"– zarr (requireszarr>=3.0) viaPersistentTensorDict. Passfilename=<path or store>in kwargs."shared"– CPU shared-memory tensors."redis"/"dragonfly"– delegates toTensorDictStore.from_schema().
device – Device for the resulting tensors (ignored by some backends).
**kwargs – Backend-specific arguments forwarded to the underlying constructor (e.g.
prefixfor memmap,filenamefor h5,host/portfor redis).
- Returns:
A new
TensorDictBasesubclass instance with pre-allocated (zero-filled) keys.
Examples
>>> td = TensorDict.from_schema( ... {"obs": ([84, 84, 3], torch.uint8), ... "reward": ([], torch.float32)}, ... batch_size=[1000], ... ) >>> td["obs"].shape torch.Size([1000, 84, 84, 3])
>>> import tempfile >>> with tempfile.TemporaryDirectory() as d: ... td_mm = TensorDict.from_schema( ... {"obs": ([4], torch.float32)}, ... batch_size=[8], ... storage="memmap", ... prefix=d, ... ) ... assert td_mm.is_memmap()
- classmethod from_tensordict(
- tensordict: TensorDictBase,
- non_tensordict: dict | None = None,
- safe: bool = True,
Tensor class wrapper to instantiate a new tensor class object.
- Parameters:
tensordict (TensorDictBase) – Dictionary of tensor types
non_tensordict (dict) – Dictionary with non-tensor and nested tensor class objects
safe (bool) – Whether to raise an error if the tensordict is not a TensorDictBase instance
- get(
- key: NestedKey,
- *args,
- **kwargs,
Gets the value stored with the input key.
- Parameters:
key (str, tuple of str) – key to be queried. If tuple of str it is equivalent to chained calls of getattr.
default – default value if the key is not found in the tensorclass.
- Returns:
value stored with the input key
- classmethod load(
- prefix: str | Path,
- *args,
- **kwargs,
Loads a tensordict from disk.
This class method is a proxy to
load_memmap().
- load_(
- prefix: str | Path,
- *args,
- **kwargs,
Loads a tensordict from disk within the current tensordict.
This class method is a proxy to
load_memmap_().
- classmethod load_memmap(
- prefix: str | Path,
- device: device | None = None,
- non_blocking: bool = False,
- *,
- out: TensorDictBase | None = None,
- robust_key: bool | None = True,
- subpath: NestedKey | None = None,
- mode: str = 'r',
- num_threads: int = 0,
- allow_pickle: bool | None = None,
Loads a memory-mapped tensordict from disk.
- Parameters:
prefix (str or Path to folder) – the path to the folder where the saved tensordict should be fetched, or the path to a memmap archive file written through
save(..., archive=True)/ a".tdz"prefix (or packed withpack_memmap()). Archives are memory-mapped once and every leaf is exposed as a zero-copy view into the mapping: only the pages of the leaves that are actually accessed are read from disk. Unlike directory-backed tensordicts, in-place writes to the leaves of an archive-loaded tensordict do not propagate to the file.device (torch.device or equivalent, optional) – if provided, the data will be asynchronously cast to that device. Supports “meta” device, in which case the data isn’t loaded but a set of empty “meta” tensors are created. This is useful to get a sense of the total model size and structure without actually opening any file.
non_blocking (bool, optional) – if
True, synchronize won’t be called after loading tensors on device. Defaults toFalse.out (TensorDictBase, optional) – optional tensordict where the data should be written.
robust_key (bool, optional) – if
True(default), expects robust key encoding was used when saving and decodes filenames accordingly. IfFalse, uses legacy behavior. IfNone, uses the default robust behavior.subpath (NestedKey or str path, optional) – the location of a nested tensordict to load, as a nested key (e.g.
("module", "0"), with arbitrary nesting allowed as usual) or as a"/"-separated string path (e.g."module/0"). Only that subtree is loaded. Works both for directories (equivalent to appending the path toprefix) and for archives.mode (str, optional) –
"r"(default) or"r+". Only relevant when loading an archive: with"r"the archive is mapped copy-on-write and in-place writes to the leaves stay in memory; with"r+"the mapping is shared and in-place writes propagate to the file, like directory-backed tensordicts."r+"requires uncompressed, aligned tensor payloads (i.e. archives written by tensordict withoutcompression) and is not available for nested-tensor leaves. In-place writes do not update the per-entry CRC-32 stored by the zip format;load_memmap()ignores checksums, but callrefresh_archive_checksums()before handing a modified archive to tools that verify them (unzip,unpack_memmap(), …). Directory prefixes are always write-through and ignore this argument.num_threads (int, optional) – number of threads used to decompress the leaves of a compressed archive (deflate entries are inflated in parallel, which scales nearly linearly). Without compression, loading is a metadata-only operation and this argument has no effect. Defaults to
0(sequential).allow_pickle (bool, optional) – whether pickled non-tensor fields may be loaded. Pickle can execute arbitrary code, so pass
Trueonly for data from a trusted source andFalsefor untrusted data. During the 0.14 compatibility window, omitting this option loads pickle with aFutureWarning; the default will change toFalsein 0.15. Saves without a pickle sidecar do not require this option.
Examples
>>> from tensordict import TensorDict >>> td = TensorDict.fromkeys(["a", "b", "c", ("nested", "e")], 0) >>> td.memmap("./saved_td") >>> td_load = TensorDict.load_memmap("./saved_td") >>> assert (td == td_load).all()
This method also allows loading nested tensordicts.
Examples
>>> nested = TensorDict.load_memmap("./saved_td/nested") >>> assert nested["e"] == 0
A tensordict can also be loaded on “meta” device or, alternatively, as a fake tensor.
Examples
>>> import tempfile >>> td = TensorDict({"a": torch.zeros(()), "b": {"c": torch.zeros(())}}) >>> with tempfile.TemporaryDirectory() as path: ... td.save(path) ... td_load = TensorDict.load_memmap(path, device="meta") ... print("meta:", td_load) ... from torch._subclasses import FakeTensorMode ... with FakeTensorMode(): ... td_load = TensorDict.load_memmap(path) ... print("fake:", td_load) meta: TensorDict( fields={ a: Tensor(shape=torch.Size([]), device=meta, dtype=torch.float32, is_shared=False), b: TensorDict( fields={ c: Tensor(shape=torch.Size([]), device=meta, dtype=torch.float32, is_shared=False)}, batch_size=torch.Size([]), device=meta, is_shared=False)}, batch_size=torch.Size([]), device=meta, is_shared=False) fake: TensorDict( fields={ a: FakeTensor(shape=torch.Size([]), device=cpu, dtype=torch.float32, is_shared=False), b: TensorDict( fields={ c: FakeTensor(shape=torch.Size([]), device=cpu, dtype=torch.float32, is_shared=False)}, batch_size=torch.Size([]), device=cpu, is_shared=False)}, batch_size=torch.Size([]), device=cpu, is_shared=False)
- load_state_dict(
- state_dict: dict[str, Any],
- strict=True,
- assign=False,
- from_flatten=None,
Loads a state_dict into the tensorclass.
Supports both the new format (logical keys with
_metadata) and the legacy format (_tensordict/_non_tensordictwrapper keys).
- memmap(
- prefix: str | None = None,
- copy_existing: bool = False,
- *,
- num_threads: int = 0,
- return_early: bool = False,
- share_non_tensor: bool = False,
- existsok: bool = True,
- robust_key: bool | None = True,
- archive: bool | None = None,
- compression: str | int | None = None,
Writes all tensors onto a corresponding memory-mapped Tensor in a new tensordict.
- Parameters:
prefix (str) – directory prefix where the memory-mapped tensors will be stored. The directory tree structure will mimic the tensordict’s. If
prefixends with".tdz"(orarchive=Trueis passed), a single-file archive is written instead of a directory: a standard zip file whose entries replicate the memmap directory layout. Seearchivebelow.copy_existing (bool) – If False (default), an exception will be raised if an entry in the tensordict is already a tensor stored on disk with an associated file, but is not saved in the correct location according to prefix. If
True, any existing Tensor will be copied to the new location.
- Keyword Arguments:
num_threads (int, optional) – the number of threads used to write the memmap tensors. Defaults to 0.
return_early (bool, optional) – if
Trueandnum_threads>0, the method will return a future of the tensordict.share_non_tensor (bool, optional) – if
True, the non-tensor data will be shared between the processes and writing operation (such as inplace update or set) on any of the workers within a single node will update the value on all other workers. If the number of non_tensor leaves is high (e.g., sharing large stacks of non-tensor data) this may result in OOM or similar errors. Defaults toFalse.existsok (bool, optional) – if
False, an exception will be raised if a tensor already exists in the same path. Defaults toTrue.robust_key (bool, optional) – if
True(default), uses robust key encoding that safely handles keys with path separators and special characters. IfFalse, uses legacy behavior (keys used as-is). IfNone, uses the default robust behavior.archive (bool, optional) – if
True,prefixdesignates a single file rather than a directory and the tensordict is written as a memmap archive: a zip file mirroring the memmap directory tree, with tensor payloads stored uncompressed and aligned so thatload_memmap()can memory-map the file and expose every leaf as a zero-copy view. IfNone(default), archive mode is enabled whenprefixends with".tdz". The result ofload_memmap()on an archive behaves like the result offrom_consolidated(): all leaves are views into a single storage, and in-place writes do not propagate to the file. Archives and memmap directories are mutually convertible withpack_memmap()/unpack_memmap()(or any zip tool). Note that archives are written sequentially (single data pass) andnum_threadshas no effect on them.compression (str or int, optional) – compression for archive entries (
"stored","deflate","bzip2","lzma"or azipfileconstant). Defaults to"stored"(uncompressed), which is what enables zero-copy loading. Compressed archives load correctly but leaves are decompressed in memory on access. Only valid in archive mode.
The TensorDict is then locked, meaning that any writing operations that isn’t in-place will throw an exception (eg, rename, set or remove an entry). Once the tensordict is unlocked, the memory-mapped attribute is turned to
False, because cross-process identity is not guaranteed anymore.- Returns:
A new tensordict with the tensors stored on disk if
return_early=False, otherwise aTensorDictFutureinstance.
Note
Serialising in this fashion might be slow with deeply nested tensordicts, so it is not recommended to call this method inside a training loop.
- memmap_(
- prefix: str | None = None,
- copy_existing: bool = False,
- *,
- num_threads: int = 0,
- return_early: bool = False,
- share_non_tensor: bool = False,
- existsok: bool = True,
- robust_key: bool | None = True,
Writes all tensors onto a corresponding memory-mapped Tensor, in-place.
- Parameters:
prefix (str) – directory prefix where the memory-mapped tensors will be stored. The directory tree structure will mimic the tensordict’s.
copy_existing (bool) – If False (default), an exception will be raised if an entry in the tensordict is already a tensor stored on disk with an associated file, but is not saved in the correct location according to prefix. If
True, any existing Tensor will be copied to the new location.
- Keyword Arguments:
num_threads (int, optional) – the number of threads used to write the memmap tensors. Defaults to 0.
return_early (bool, optional) – if
Trueandnum_threads>0, the method will return a future of the tensordict. The resulting tensordict can be queried using future.result().share_non_tensor (bool, optional) – if
True, the non-tensor data will be shared between the processes and writing operation (such as inplace update or set) on any of the workers within a single node will update the value on all other workers. If the number of non-tensor leaves is high (e.g., sharing large stacks of non-tensor data) this may result in OOM or similar errors. Defaults toFalse.existsok (bool, optional) – if
False, an exception will be raised if a tensor already exists in the same path. Defaults toTrue.robust_key (bool, optional) – if
True(default), uses robust key encoding that safely handles keys with path separators and special characters. IfFalse, uses legacy behavior (keys used as-is). IfNone, uses the default robust behavior.
The TensorDict is then locked, meaning that any writing operations that isn’t in-place will throw an exception (eg, rename, set or remove an entry). Once the tensordict is unlocked, the memory-mapped attribute is turned to
False, because cross-process identity is not guaranteed anymore.- Returns:
self if
return_early=False, otherwise aTensorDictFutureinstance.
Note
Serialising in this fashion might be slow with deeply nested tensordicts, so it is not recommended to call this method inside a training loop.
- memmap_like(
- prefix: str | None = None,
- copy_existing: bool = False,
- *,
- existsok: bool = True,
- num_threads: int = 0,
- return_early: bool = False,
- share_non_tensor: bool = False,
- robust_key: bool | None = True,
- archive: bool | None = None,
Creates a contentless Memory-mapped tensordict with the same shapes as the original one.
- Parameters:
prefix (str) – directory prefix where the memory-mapped tensors will be stored. The directory tree structure will mimic the tensordict’s. If
prefixends with".tdz"(orarchive=Trueis passed), a preallocated single-file archive is created instead. Seearchivebelow.copy_existing (bool) – If False (default), an exception will be raised if an entry in the tensordict is already a tensor stored on disk with an associated file, but is not saved in the correct location according to prefix. If
True, any existing Tensor will be copied to the new location.
- Keyword Arguments:
num_threads (int, optional) – the number of threads used to write the memmap tensors. Defaults to 0.
return_early (bool, optional) – if
Trueandnum_threads>0, the method will return a future of the tensordict.share_non_tensor (bool, optional) – if
True, the non-tensor data will be shared between the processes and writing operation (such as inplace update or set) on any of the workers within a single node will update the value on all other workers. If the number of non-tensor leaves is high (e.g., sharing large stacks of non-tensor data) this may result in OOM or similar errors. Defaults toFalse.existsok (bool, optional) – if
False, an exception will be raised if a tensor already exists in the same path. Defaults toTrue.robust_key (bool, optional) – if
True(default), uses robust key encoding that safely handles keys with path separators and special characters. IfFalse, uses legacy behavior (keys used as-is). IfNone, uses the default robust behavior.archive (bool, optional) – if
True,prefixdesignates a single file and a preallocated, zero-filled memmap archive is created and loaded back withload_memmap(prefix, mode="r+"): the returned tensordict writes through to the archive. IfNone(default), archive mode is enabled whenprefixends with".tdz". In-place writes leave the zip per-entry checksums stale; callrefresh_archive_checksums()before handing the archive to tools that verify them. Nested tensors are not supported in this mode.
The TensorDict is then locked, meaning that any writing operations that isn’t in-place will throw an exception (eg, rename, set or remove an entry). Once the tensordict is unlocked, the memory-mapped attribute is turned to
False, because cross-process identity is not guaranteed anymore.- Returns:
A new
TensorDictinstance with data stored as memory-mapped tensors ifreturn_early=False, otherwise aTensorDictFutureinstance.
Note
This is the recommended method to write a set of large buffers on disk, as
memmap_()will copy the information, which can be slow for large content.Examples
>>> td = TensorDict({ ... "a": torch.zeros((3, 64, 64), dtype=torch.uint8), ... "b": torch.zeros(1, dtype=torch.int64), ... }, batch_size=[]).expand(1_000_000) # expand does not allocate new memory >>> buffer = td.memmap_like("/path/to/dataset")
- memmap_refresh_(
- *,
- allow_pickle: bool | None = None,
Refreshes the content of the memory-mapped tensordict if it has a
saved_path.This method will raise an exception if no path is associated with it.
- Parameters:
allow_pickle (bool, optional) – whether pickled non-tensor fields may be loaded. See
load_memmap().
- property n_far_nodes: int#
Number of (far,far) node-to-node pairs (each = one kernel eval).
- property n_fn: int#
Number of (far,near) target-node-to-source-point pairs.
- property n_near: int#
Number of (near,near) exact individual interaction pairs.
- property n_nf: int#
Number of (near,far) target-point-to-source-node pairs.
- save(
- prefix: str | None = None,
- copy_existing: bool = False,
- *,
- num_threads: int = 0,
- return_early: bool = False,
- share_non_tensor: bool = False,
- robust_key: bool | None = True,
- archive: bool | None = None,
- compression: str | int | None = None,
Saves the tensordict to disk.
This function is a proxy to
memmap().
- select(
- *keys,
- inplace: bool = False,
- strict: bool = True,
- as_tensordict: bool = False,
TensorClass-specific select that supports
as_tensordict.
- set(
- key: NestedKey,
- value: Any,
- inplace: bool = False,
- non_blocking: bool = False,
Sets a new key-value pair.
- Parameters:
key (str, tuple of str) – name of the key to be set. If tuple of str it is equivalent to chained calls of getattr followed by a final setattr.
value (Any) – value to be stored in the tensorclass
inplace (bool, optional) – if
True, set will tentatively try to update the value in-place. IfFalseor if the key isn’t present, the value will be simply written at its destination.
- Returns:
self
- state_dict(
- destination=None,
- prefix='',
- keep_vars=False,
- flatten=True,
Returns a state_dict with logical keys, matching TensorDictBase conventions.
Tensor fields appear as data keys. Non-tensor fields (strings, ints, etc.) and the tensorclass type are stored in
_metadata. This replaces the legacy_tensordict/_non_tensordictwrapper format.
- to_tensordict(
- *,
- retain_none: bool | None = None,
Convert the tensorclass into a regular TensorDict.
Makes a copy of all entries. Memmap and shared memory tensors are converted to regular tensors.
- Parameters:
retain_none (bool) – if
True, theNonevalues will be written in the tensordict. Otherwise they will be discrarded. Default:True.- Returns:
A new TensorDict object containing the same values as the tensorclass.
- unbind(dim: int)#
Returns a tuple of indexed tensorclass instances unbound along the indicated dimension.
Resulting tensorclass instances will share the storage of the initial tensorclass instance.
- validate() None[source]#
Check internal consistency of the interaction plan.
Verifies shape pairing, non-negativity, and fn_broadcast bounds. Raises
ValueErroron any inconsistency. Intended to be called behind anot torch.compiler.is_compiling()guard so it is zero-cost undertorch.compile.- Raises:
ValueError – If any internal consistency check fails.
- class physicsnemo.mesh.spatial.SourceAggregates(
- node_centroid: jaxtyping.Float[Tensor, 'n_nodes n_dims'],
- node_source_data: tensordict._td.TensorDict | None,
- *,
- batch_size,
- device=None,
- names=None,
Bases:
object- property device: device#
Retrieves the device type of tensor class.
- dumps(
- prefix: str | None = None,
- copy_existing: bool = False,
- *,
- num_threads: int = 0,
- return_early: bool = False,
- share_non_tensor: bool = False,
- robust_key: bool | None = True,
- archive: bool | None = None,
- compression: str | int | None = None,
Saves the tensordict to disk.
This function is a proxy to
memmap().
- classmethod fields()#
Return a tuple describing the fields of this dataclass.
Accepts a dataclass or an instance of one. Tuple elements are of type Field.
- from_csv(
- *,
- auto_batch_size: bool = False,
- batch_dims: int | None = None,
- device: device | None = None,
- batch_size: Size | None = None,
- separator: str | None = None,
- dtype: dtype | None = None,
- **kwargs,
Creates a TensorDict from a CSV file.
Requires either pandas or pyarrow to be installed.
- Parameters:
path (str or Path) – Path to the CSV file.
- Keyword Arguments:
auto_batch_size (bool, optional) – If
True, the batch size will be computed automatically. Defaults toFalse.batch_dims (int, optional) – If
auto_batch_sizeisTrue, defines how many dimensions the output tensordict should have. Defaults toNone.device (torch.device, optional) – The device for tensor data. Defaults to
None.batch_size (torch.Size, optional) – The batch size. Defaults to
[num_rows].separator (str, optional) – If provided, column names are split on this separator to create nested TensorDicts. Defaults to
None.dtype (torch.dtype, optional) – If provided, all numeric columns are cast to this dtype. Defaults to
None.**kwargs – Additional keyword arguments forwarded to the CSV reader (
pandas.read_csvorpyarrow.csv.read_csv).
- Returns:
A TensorDict representation of the CSV data.
Examples
>>> td = TensorDict.from_csv("data.csv") >>> td = TensorDict.from_csv("data.csv", separator=".", dtype=torch.float32)
- from_json(
- *,
- auto_batch_size: bool = False,
- batch_dims: int | None = None,
- device: device | None = None,
- batch_size: Size | None = None,
- separator: str | None = None,
- dtype: dtype | None = None,
- lines: bool = False,
- **kwargs,
Creates a TensorDict from a JSON file.
Supports both standard JSON (array of records) and JSON Lines format. For nested JSON objects, use
from_dict()instead.Requires pandas for best results. Falls back to stdlib
jsonfor simple cases.- Parameters:
path (str or Path) – Path to the JSON file.
- Keyword Arguments:
auto_batch_size (bool, optional) – If
True, the batch size will be computed automatically. Defaults toFalse.batch_dims (int, optional) – If
auto_batch_sizeisTrue, defines how many dimensions the output tensordict should have. Defaults toNone.device (torch.device, optional) – The device for tensor data. Defaults to
None.batch_size (torch.Size, optional) – The batch size. Defaults to
[num_rows].separator (str, optional) – If provided, column names are split on this separator to create nested TensorDicts. Defaults to
None.dtype (torch.dtype, optional) – If provided, all numeric columns are cast to this dtype. Defaults to
None.lines (bool, optional) – If
True, reads the file as JSON Lines (one JSON object per line). Defaults toFalse.**kwargs – Additional keyword arguments forwarded to the JSON reader.
- Returns:
A TensorDict representation of the JSON data.
Examples
>>> td = TensorDict.from_json("data.json") >>> td = TensorDict.from_json("data.jsonl", lines=True)
- from_pandas(
- *,
- auto_batch_size: bool = False,
- batch_dims: int | None = None,
- device: device | None = None,
- batch_size: Size | None = None,
- separator: str | None = None,
- dtype: dtype | None = None,
Converts a pandas DataFrame to a TensorDict.
Numeric columns become tensors, string/object columns become
NonTensorData.- Parameters:
dataframe (pd.DataFrame) – The pandas DataFrame to convert.
- Keyword Arguments:
auto_batch_size (bool, optional) – If
True, the batch size will be computed automatically. Defaults toFalse.batch_dims (int, optional) – If
auto_batch_sizeisTrue, defines how many dimensions the output tensordict should have. Defaults toNone.device (torch.device, optional) – The device for tensor data. Defaults to
None.batch_size (torch.Size, optional) – The batch size. Defaults to
[num_rows].separator (str, optional) – If provided, column names are split on this separator to create nested TensorDicts. For example, with
separator=".", a column"obs.x"becomestd["obs", "x"]. Defaults toNone.dtype (torch.dtype, optional) – If provided, all numeric columns are cast to this dtype. Defaults to
None.
- Returns:
A TensorDict representation of the DataFrame.
Examples
>>> import pandas as pd >>> df = pd.DataFrame({"a": [1, 2, 3], "b": [4.0, 5.0, 6.0]}) >>> td = TensorDict.from_pandas(df) >>> print(td) TensorDict( fields={ a: Tensor(shape=torch.Size([3]), device=cpu, dtype=torch.int64, is_shared=False), b: Tensor(shape=torch.Size([3]), device=cpu, dtype=torch.float64, is_shared=False)}, batch_size=torch.Size([3]), device=None, is_shared=False)
- from_parquet(
- *,
- auto_batch_size: bool = False,
- batch_dims: int | None = None,
- device: device | None = None,
- batch_size: Size | None = None,
- separator: str | None = None,
- dtype: dtype | None = None,
- columns: list[str] | None = None,
- **kwargs,
Creates a TensorDict from a Parquet file.
Requires either pyarrow or pandas to be installed. Prefers pyarrow when available for better performance.
- Parameters:
path (str or Path) – Path to the Parquet file.
- Keyword Arguments:
auto_batch_size (bool, optional) – If
True, the batch size will be computed automatically. Defaults toFalse.batch_dims (int, optional) – If
auto_batch_sizeisTrue, defines how many dimensions the output tensordict should have. Defaults toNone.device (torch.device, optional) – The device for tensor data. Defaults to
None.batch_size (torch.Size, optional) – The batch size. Defaults to
[num_rows].separator (str, optional) – If provided, column names are split on this separator to create nested TensorDicts. Defaults to
None.dtype (torch.dtype, optional) – If provided, all numeric columns are cast to this dtype. Defaults to
None.columns (list of str, optional) – If provided, only read these columns from the file. Defaults to
None(all columns).**kwargs – Additional keyword arguments forwarded to the Parquet reader.
- Returns:
A TensorDict representation of the Parquet data.
Examples
>>> td = TensorDict.from_parquet("data.parquet") >>> td = TensorDict.from_parquet("data.parquet", columns=["obs", "reward"])
- from_schema(
- *,
- batch_size: Sequence[int] | Size | None = None,
- storage: str | None = None,
- device=None,
- **kwargs,
Pre-allocate a zero-filled TensorDict from a schema.
Creates a
TensorDictBasewhose storage backend is selected bystorage. Each entry inschemamaps a field name to an(element_shape, dtype)pair; the full stored shape is[*batch_size, *element_shape].- Parameters:
schema – Mapping from field name to
(element_shape, dtype).element_shapeis the per-element shape (excludingbatch_size).- Keyword Arguments:
batch_size – Overall batch dimensions prepended to every element shape. Defaults to
().storage (str or None) –
Backend selector:
None– plainTensorDictwith regular tensors."memmap"– memory-mapped tensors on disk. Passprefix=<dir>in kwargs."h5"– HDF5 viaPersistentTensorDict. Passfilename=<path>in kwargs."zarr"– zarr (requireszarr>=3.0) viaPersistentTensorDict. Passfilename=<path or store>in kwargs."shared"– CPU shared-memory tensors."redis"/"dragonfly"– delegates toTensorDictStore.from_schema().
device – Device for the resulting tensors (ignored by some backends).
**kwargs – Backend-specific arguments forwarded to the underlying constructor (e.g.
prefixfor memmap,filenamefor h5,host/portfor redis).
- Returns:
A new
TensorDictBasesubclass instance with pre-allocated (zero-filled) keys.
Examples
>>> td = TensorDict.from_schema( ... {"obs": ([84, 84, 3], torch.uint8), ... "reward": ([], torch.float32)}, ... batch_size=[1000], ... ) >>> td["obs"].shape torch.Size([1000, 84, 84, 3])
>>> import tempfile >>> with tempfile.TemporaryDirectory() as d: ... td_mm = TensorDict.from_schema( ... {"obs": ([4], torch.float32)}, ... batch_size=[8], ... storage="memmap", ... prefix=d, ... ) ... assert td_mm.is_memmap()
- classmethod from_tensordict(
- tensordict: TensorDictBase,
- non_tensordict: dict | None = None,
- safe: bool = True,
Tensor class wrapper to instantiate a new tensor class object.
- Parameters:
tensordict (TensorDictBase) – Dictionary of tensor types
non_tensordict (dict) – Dictionary with non-tensor and nested tensor class objects
safe (bool) – Whether to raise an error if the tensordict is not a TensorDictBase instance
- get(
- key: NestedKey,
- *args,
- **kwargs,
Gets the value stored with the input key.
- Parameters:
key (str, tuple of str) – key to be queried. If tuple of str it is equivalent to chained calls of getattr.
default – default value if the key is not found in the tensorclass.
- Returns:
value stored with the input key
- classmethod load(
- prefix: str | Path,
- *args,
- **kwargs,
Loads a tensordict from disk.
This class method is a proxy to
load_memmap().
- load_(prefix: str | Path, *args, **kwargs)#
Loads a tensordict from disk within the current tensordict.
This class method is a proxy to
load_memmap_().
- classmethod load_memmap(
- prefix: str | Path,
- device: device | None = None,
- non_blocking: bool = False,
- *,
- out: TensorDictBase | None = None,
- robust_key: bool | None = True,
- subpath: NestedKey | None = None,
- mode: str = 'r',
- num_threads: int = 0,
- allow_pickle: bool | None = None,
Loads a memory-mapped tensordict from disk.
- Parameters:
prefix (str or Path to folder) – the path to the folder where the saved tensordict should be fetched, or the path to a memmap archive file written through
save(..., archive=True)/ a".tdz"prefix (or packed withpack_memmap()). Archives are memory-mapped once and every leaf is exposed as a zero-copy view into the mapping: only the pages of the leaves that are actually accessed are read from disk. Unlike directory-backed tensordicts, in-place writes to the leaves of an archive-loaded tensordict do not propagate to the file.device (torch.device or equivalent, optional) – if provided, the data will be asynchronously cast to that device. Supports “meta” device, in which case the data isn’t loaded but a set of empty “meta” tensors are created. This is useful to get a sense of the total model size and structure without actually opening any file.
non_blocking (bool, optional) – if
True, synchronize won’t be called after loading tensors on device. Defaults toFalse.out (TensorDictBase, optional) – optional tensordict where the data should be written.
robust_key (bool, optional) – if
True(default), expects robust key encoding was used when saving and decodes filenames accordingly. IfFalse, uses legacy behavior. IfNone, uses the default robust behavior.subpath (NestedKey or str path, optional) – the location of a nested tensordict to load, as a nested key (e.g.
("module", "0"), with arbitrary nesting allowed as usual) or as a"/"-separated string path (e.g."module/0"). Only that subtree is loaded. Works both for directories (equivalent to appending the path toprefix) and for archives.mode (str, optional) –
"r"(default) or"r+". Only relevant when loading an archive: with"r"the archive is mapped copy-on-write and in-place writes to the leaves stay in memory; with"r+"the mapping is shared and in-place writes propagate to the file, like directory-backed tensordicts."r+"requires uncompressed, aligned tensor payloads (i.e. archives written by tensordict withoutcompression) and is not available for nested-tensor leaves. In-place writes do not update the per-entry CRC-32 stored by the zip format;load_memmap()ignores checksums, but callrefresh_archive_checksums()before handing a modified archive to tools that verify them (unzip,unpack_memmap(), …). Directory prefixes are always write-through and ignore this argument.num_threads (int, optional) – number of threads used to decompress the leaves of a compressed archive (deflate entries are inflated in parallel, which scales nearly linearly). Without compression, loading is a metadata-only operation and this argument has no effect. Defaults to
0(sequential).allow_pickle (bool, optional) – whether pickled non-tensor fields may be loaded. Pickle can execute arbitrary code, so pass
Trueonly for data from a trusted source andFalsefor untrusted data. During the 0.14 compatibility window, omitting this option loads pickle with aFutureWarning; the default will change toFalsein 0.15. Saves without a pickle sidecar do not require this option.
Examples
>>> from tensordict import TensorDict >>> td = TensorDict.fromkeys(["a", "b", "c", ("nested", "e")], 0) >>> td.memmap("./saved_td") >>> td_load = TensorDict.load_memmap("./saved_td") >>> assert (td == td_load).all()
This method also allows loading nested tensordicts.
Examples
>>> nested = TensorDict.load_memmap("./saved_td/nested") >>> assert nested["e"] == 0
A tensordict can also be loaded on “meta” device or, alternatively, as a fake tensor.
Examples
>>> import tempfile >>> td = TensorDict({"a": torch.zeros(()), "b": {"c": torch.zeros(())}}) >>> with tempfile.TemporaryDirectory() as path: ... td.save(path) ... td_load = TensorDict.load_memmap(path, device="meta") ... print("meta:", td_load) ... from torch._subclasses import FakeTensorMode ... with FakeTensorMode(): ... td_load = TensorDict.load_memmap(path) ... print("fake:", td_load) meta: TensorDict( fields={ a: Tensor(shape=torch.Size([]), device=meta, dtype=torch.float32, is_shared=False), b: TensorDict( fields={ c: Tensor(shape=torch.Size([]), device=meta, dtype=torch.float32, is_shared=False)}, batch_size=torch.Size([]), device=meta, is_shared=False)}, batch_size=torch.Size([]), device=meta, is_shared=False) fake: TensorDict( fields={ a: FakeTensor(shape=torch.Size([]), device=cpu, dtype=torch.float32, is_shared=False), b: TensorDict( fields={ c: FakeTensor(shape=torch.Size([]), device=cpu, dtype=torch.float32, is_shared=False)}, batch_size=torch.Size([]), device=cpu, is_shared=False)}, batch_size=torch.Size([]), device=cpu, is_shared=False)
- load_state_dict(
- state_dict: dict[str, Any],
- strict=True,
- assign=False,
- from_flatten=None,
Loads a state_dict into the tensorclass.
Supports both the new format (logical keys with
_metadata) and the legacy format (_tensordict/_non_tensordictwrapper keys).
- memmap(
- prefix: str | None = None,
- copy_existing: bool = False,
- *,
- num_threads: int = 0,
- return_early: bool = False,
- share_non_tensor: bool = False,
- existsok: bool = True,
- robust_key: bool | None = True,
- archive: bool | None = None,
- compression: str | int | None = None,
Writes all tensors onto a corresponding memory-mapped Tensor in a new tensordict.
- Parameters:
prefix (str) – directory prefix where the memory-mapped tensors will be stored. The directory tree structure will mimic the tensordict’s. If
prefixends with".tdz"(orarchive=Trueis passed), a single-file archive is written instead of a directory: a standard zip file whose entries replicate the memmap directory layout. Seearchivebelow.copy_existing (bool) – If False (default), an exception will be raised if an entry in the tensordict is already a tensor stored on disk with an associated file, but is not saved in the correct location according to prefix. If
True, any existing Tensor will be copied to the new location.
- Keyword Arguments:
num_threads (int, optional) – the number of threads used to write the memmap tensors. Defaults to 0.
return_early (bool, optional) – if
Trueandnum_threads>0, the method will return a future of the tensordict.share_non_tensor (bool, optional) – if
True, the non-tensor data will be shared between the processes and writing operation (such as inplace update or set) on any of the workers within a single node will update the value on all other workers. If the number of non_tensor leaves is high (e.g., sharing large stacks of non-tensor data) this may result in OOM or similar errors. Defaults toFalse.existsok (bool, optional) – if
False, an exception will be raised if a tensor already exists in the same path. Defaults toTrue.robust_key (bool, optional) – if
True(default), uses robust key encoding that safely handles keys with path separators and special characters. IfFalse, uses legacy behavior (keys used as-is). IfNone, uses the default robust behavior.archive (bool, optional) – if
True,prefixdesignates a single file rather than a directory and the tensordict is written as a memmap archive: a zip file mirroring the memmap directory tree, with tensor payloads stored uncompressed and aligned so thatload_memmap()can memory-map the file and expose every leaf as a zero-copy view. IfNone(default), archive mode is enabled whenprefixends with".tdz". The result ofload_memmap()on an archive behaves like the result offrom_consolidated(): all leaves are views into a single storage, and in-place writes do not propagate to the file. Archives and memmap directories are mutually convertible withpack_memmap()/unpack_memmap()(or any zip tool). Note that archives are written sequentially (single data pass) andnum_threadshas no effect on them.compression (str or int, optional) – compression for archive entries (
"stored","deflate","bzip2","lzma"or azipfileconstant). Defaults to"stored"(uncompressed), which is what enables zero-copy loading. Compressed archives load correctly but leaves are decompressed in memory on access. Only valid in archive mode.
The TensorDict is then locked, meaning that any writing operations that isn’t in-place will throw an exception (eg, rename, set or remove an entry). Once the tensordict is unlocked, the memory-mapped attribute is turned to
False, because cross-process identity is not guaranteed anymore.- Returns:
A new tensordict with the tensors stored on disk if
return_early=False, otherwise aTensorDictFutureinstance.
Note
Serialising in this fashion might be slow with deeply nested tensordicts, so it is not recommended to call this method inside a training loop.
- memmap_(
- prefix: str | None = None,
- copy_existing: bool = False,
- *,
- num_threads: int = 0,
- return_early: bool = False,
- share_non_tensor: bool = False,
- existsok: bool = True,
- robust_key: bool | None = True,
Writes all tensors onto a corresponding memory-mapped Tensor, in-place.
- Parameters:
prefix (str) – directory prefix where the memory-mapped tensors will be stored. The directory tree structure will mimic the tensordict’s.
copy_existing (bool) – If False (default), an exception will be raised if an entry in the tensordict is already a tensor stored on disk with an associated file, but is not saved in the correct location according to prefix. If
True, any existing Tensor will be copied to the new location.
- Keyword Arguments:
num_threads (int, optional) – the number of threads used to write the memmap tensors. Defaults to 0.
return_early (bool, optional) – if
Trueandnum_threads>0, the method will return a future of the tensordict. The resulting tensordict can be queried using future.result().share_non_tensor (bool, optional) – if
True, the non-tensor data will be shared between the processes and writing operation (such as inplace update or set) on any of the workers within a single node will update the value on all other workers. If the number of non-tensor leaves is high (e.g., sharing large stacks of non-tensor data) this may result in OOM or similar errors. Defaults toFalse.existsok (bool, optional) – if
False, an exception will be raised if a tensor already exists in the same path. Defaults toTrue.robust_key (bool, optional) – if
True(default), uses robust key encoding that safely handles keys with path separators and special characters. IfFalse, uses legacy behavior (keys used as-is). IfNone, uses the default robust behavior.
The TensorDict is then locked, meaning that any writing operations that isn’t in-place will throw an exception (eg, rename, set or remove an entry). Once the tensordict is unlocked, the memory-mapped attribute is turned to
False, because cross-process identity is not guaranteed anymore.- Returns:
self if
return_early=False, otherwise aTensorDictFutureinstance.
Note
Serialising in this fashion might be slow with deeply nested tensordicts, so it is not recommended to call this method inside a training loop.
- memmap_like(
- prefix: str | None = None,
- copy_existing: bool = False,
- *,
- existsok: bool = True,
- num_threads: int = 0,
- return_early: bool = False,
- share_non_tensor: bool = False,
- robust_key: bool | None = True,
- archive: bool | None = None,
Creates a contentless Memory-mapped tensordict with the same shapes as the original one.
- Parameters:
prefix (str) – directory prefix where the memory-mapped tensors will be stored. The directory tree structure will mimic the tensordict’s. If
prefixends with".tdz"(orarchive=Trueis passed), a preallocated single-file archive is created instead. Seearchivebelow.copy_existing (bool) – If False (default), an exception will be raised if an entry in the tensordict is already a tensor stored on disk with an associated file, but is not saved in the correct location according to prefix. If
True, any existing Tensor will be copied to the new location.
- Keyword Arguments:
num_threads (int, optional) – the number of threads used to write the memmap tensors. Defaults to 0.
return_early (bool, optional) – if
Trueandnum_threads>0, the method will return a future of the tensordict.share_non_tensor (bool, optional) – if
True, the non-tensor data will be shared between the processes and writing operation (such as inplace update or set) on any of the workers within a single node will update the value on all other workers. If the number of non-tensor leaves is high (e.g., sharing large stacks of non-tensor data) this may result in OOM or similar errors. Defaults toFalse.existsok (bool, optional) – if
False, an exception will be raised if a tensor already exists in the same path. Defaults toTrue.robust_key (bool, optional) – if
True(default), uses robust key encoding that safely handles keys with path separators and special characters. IfFalse, uses legacy behavior (keys used as-is). IfNone, uses the default robust behavior.archive (bool, optional) – if
True,prefixdesignates a single file and a preallocated, zero-filled memmap archive is created and loaded back withload_memmap(prefix, mode="r+"): the returned tensordict writes through to the archive. IfNone(default), archive mode is enabled whenprefixends with".tdz". In-place writes leave the zip per-entry checksums stale; callrefresh_archive_checksums()before handing the archive to tools that verify them. Nested tensors are not supported in this mode.
The TensorDict is then locked, meaning that any writing operations that isn’t in-place will throw an exception (eg, rename, set or remove an entry). Once the tensordict is unlocked, the memory-mapped attribute is turned to
False, because cross-process identity is not guaranteed anymore.- Returns:
A new
TensorDictinstance with data stored as memory-mapped tensors ifreturn_early=False, otherwise aTensorDictFutureinstance.
Note
This is the recommended method to write a set of large buffers on disk, as
memmap_()will copy the information, which can be slow for large content.Examples
>>> td = TensorDict({ ... "a": torch.zeros((3, 64, 64), dtype=torch.uint8), ... "b": torch.zeros(1, dtype=torch.int64), ... }, batch_size=[]).expand(1_000_000) # expand does not allocate new memory >>> buffer = td.memmap_like("/path/to/dataset")
- memmap_refresh_(*, allow_pickle: bool | None = None)#
Refreshes the content of the memory-mapped tensordict if it has a
saved_path.This method will raise an exception if no path is associated with it.
- Parameters:
allow_pickle (bool, optional) – whether pickled non-tensor fields may be loaded. See
load_memmap().
- node_centroid: Float[Tensor, 'n_nodes n_dims']#
Area-weighted centroid per node.
- node_source_data: TensorDict | None#
Area-weighted average source features per node, or
Noneif no per-source features. Hasbatch_size=(n_nodes,).
- save(
- prefix: str | None = None,
- copy_existing: bool = False,
- *,
- num_threads: int = 0,
- return_early: bool = False,
- share_non_tensor: bool = False,
- robust_key: bool | None = True,
- archive: bool | None = None,
- compression: str | int | None = None,
Saves the tensordict to disk.
This function is a proxy to
memmap().
- select(
- *keys,
- inplace: bool = False,
- strict: bool = True,
- as_tensordict: bool = False,
TensorClass-specific select that supports
as_tensordict.
- set(
- key: NestedKey,
- value: Any,
- inplace: bool = False,
- non_blocking: bool = False,
Sets a new key-value pair.
- Parameters:
key (str, tuple of str) – name of the key to be set. If tuple of str it is equivalent to chained calls of getattr followed by a final setattr.
value (Any) – value to be stored in the tensorclass
inplace (bool, optional) – if
True, set will tentatively try to update the value in-place. IfFalseor if the key isn’t present, the value will be simply written at its destination.
- Returns:
self
- state_dict(
- destination=None,
- prefix='',
- keep_vars=False,
- flatten=True,
Returns a state_dict with logical keys, matching TensorDictBase conventions.
Tensor fields appear as data keys. Non-tensor fields (strings, ints, etc.) and the tensorclass type are stored in
_metadata. This replaces the legacy_tensordict/_non_tensordictwrapper format.
- to_tensordict(
- *,
- retain_none: bool | None = None,
Convert the tensorclass into a regular TensorDict.
Makes a copy of all entries. Memmap and shared memory tensors are converted to regular tensors.
- Parameters:
retain_none (bool) – if
True, theNonevalues will be written in the tensordict. Otherwise they will be discrarded. Default:True.- Returns:
A new TensorDict object containing the same values as the tensorclass.
- unbind(dim: int)#
Returns a tuple of indexed tensorclass instances unbound along the indicated dimension.
Resulting tensorclass instances will share the storage of the initial tensorclass instance.
- physicsnemo.mesh.spatial.signed_distance_field(
- mesh: Mesh,
- query_points: Float[Tensor, '... 3'],
- max_dist: float | None = None,
- use_sign_winding_number: bool = False,
Compute the signed distance to a triangle surface mesh.
Returns the signed distance, the closest surface point, and the nearest face index for each query. Delegates to the Warp-backed
physicsnemo.nn.functional.signed_distance_field()op, which runs on CPU and CUDA.- Parameters:
mesh (Mesh) – Triangle surface mesh embedded in 3D:
mesh.pointshas shape(n_vertices, 3)andmesh.cellshas shape(n_faces, 3).query_points (torch.Tensor) – Query points, shape
(..., 3).max_dist (float or None, optional) – Maximum search radius for the nearest-triangle query.
None(default) searches without bound, so the true nearest triangle is always found; a finite value restricts the search to a band and reports queries farther than it asNaN(bothsdfandhit_points) with a hit face of-1.use_sign_winding_number (bool, optional) – If
True, sign via the generalized winding number (wp.mesh_query_point_sign_winding_number), robust for non-watertight meshes. IfFalse(default), sign via the angle-weighted pseudo-normal of the closest mesh feature (wp.mesh_query_point_sign_normal), which stays correct at sharp/non-convex edges where a single face normal would flip the sign. The mesh should be watertight for reliable signs in theFalsecase.
- Returns:
(sdf, hit_points, hit_faces): signed distance per query (shapequery_points.shape[:-1]; negative inside, positive outside), the closest point on the mesh per query (shapequery_points.shape), and the index intomesh.cellsof the nearest face per query (int64, shapequery_points.shape[:-1]). Queries beyond a finitemax_distreturnNaNfor the distance and hit point and-1for the hit face.- Return type:
tuple[torch.Tensor, torch.Tensor, torch.Tensor]
- Raises:
ValueError – If
meshis not a triangle surface in 3D (n_spatial_dims == 3andn_manifold_dims == 2), ifquery_pointsdoes not have a trailing dimension of size 3, if the mesh has no faces (there is no surface to measure distance to), ifmeshandquery_pointsare on different devices, or ifmax_distis negative.
Notes
A finite
max_distis an opt-in optimization/narrow-band mode: it prunes the search to the given radius and marks out-of-band queries asNaNso a far query is never silently reported as on-surface (sdf == 0). The unbounded default never producesNaNfor a non-empty mesh.Distances are computed in float32 (inputs are cast as needed) and results are cast back to the
query_pointsdtype.(Near-)degenerate faces – repeated vertices or collinear points, which Warp’s mesh query would otherwise skip – are repaired into equivalent thin-but-valid triangles over the same longest edge before the query, so a query nearest to such a face reports the distance to its segment (to within the repair offset) rather than the distance to some farther valid face. See
_repair_degenerate_faces().