Skip to main content

A Python library for performing operations on tensors with infinite dimensions.

Project description

Infinite Tensors

A Python library for performing operations on theoretically infinite tensors using a sliding window approach. This library enables processing of large tensors without loading the entire tensor into memory.

Installation

Install using pip:

pip install infinite-tensor

What is an Infinite Tensor?

An Infinite Tensor represents an immutable tensor with one or more unbounded dimensions, defined by a deterministic function f. Instead of loading all data into memory at once, it:

  • Loads only the parts you need, when you need them
  • Processes data in manageable windows
  • Caches results so repeated reads are instant

Internally, when you index a region, the system identifies which output windows intersect that region, invokes f on each, and sums the outputs together. Results are cached, and no data outside the requested region is generated.

Key Concepts

  1. Windows: Define how your processing function sees the data

    • Fixed size (e.g., 64x64 pixels)
    • Outputs in overlapping regions are added together
    • Defined by size, stride, and offset
  2. Infinite Tensors: Immutable tensors with infinite dimensions

    • Some dimensions can be None (infinite), others must be finite
    • Defined by a deterministic function f operating on the "output window"
    • Can depend on other infinite tensors

Getting Started

1. Creating an Infinite Tensor

Always create tensors through a TileStore:

import uuid
import torch
from infinite_tensor import TensorWindow, MemoryTileStore

# Create a tile store (in-memory)
tile_store = MemoryTileStore()

# Define how each window is generated; must match the window's shape
def your_processing_function(ctx):
    # ctx is the window index (e.g., (wy, wx) for 2D). It is NOT pixel coordinates.
    return torch.ones(512, 512)

# Define the output window seen by your function
window = TensorWindow((512, 512))

# Create an infinite tensor (2D infinite)
tensor = tile_store.get_or_create(
    "my_infinite_tensor",
    shape=(None, None),         # None means infinite dimension
    f=your_processing_function, # A function that takes the index of the current output window as input: e.g (0, 0)
    output_window=window,
    tile_size=512,              # internal tile size (optional)
)

2. Using the Tensor

Just slice it like a normal tensor (computed on-demand)

result = tensor[0:1024, 0:1024]

Advanced Features

1. Caching Methods

InfiniteTensor supports two caching strategies via cache_method:

  • cache_method='indirect' (default): Window outputs are accumulated into tiles. Best for persistent storage (e.g., HDF5TileStore) since it uses the least disk space. Use tile_size to indicate the size of the tiles.

  • cache_method='direct': Window outputs are cached directly with LRU eviction. Best when you want to limit memory usage and don't need persistent storage. Use cache_limit to set the max cache size in bytes (default: 10MB), or None for unlimited. tile_size is ignored with this method.

2. Dependency Chaining

Create processing pipelines by making one infinite tensor depend on another.

In this case, f is called like f(ctx, *args_sliced), where ctx is the output window index, and args_sliced are the upstream tensors (args) sliced by args_windows.

import torch
from infinite_tensor import TensorWindow, MemoryTileStore

tile_store = MemoryTileStore()

def zeros_tensor_func(ctx):
    return torch.zeros(10, 512, 512)  # (C, H, W)

base_window = TensorWindow((10, 512, 512))
base = tile_store.get_or_create("my_tensor", (10, None, None), zeros_tensor_func, base_window)

# Define an offset window for the dependent tensor
offset_window = TensorWindow((10, 512, 512), offset=(0, -256, -256))

# The function receives the upstream window directly (already sliced)
def inc_func(ctx, prev):
    return prev + 1

dep = tile_store.get_or_create(
    "my_second_tensor",
    (10, None, None),
    inc_func,
    offset_window,
    args=(base,),
    args_windows=(offset_window,),
)

out = dep[:, 0:512, 0:512]  # ones

Note: Manually slicing dependencies inside f is not recommended, as it prevents the use of batching, and future versions may introduce automatic memory management utilizing this future.

3. Batching

Optionally, f can take in a list of tensors, instead of one at a time. The max size of the list is given by batch_size. Here is the same example as above but with batching:

import torch
from infinite_tensor import TensorWindow, MemoryTileStore

tile_store = MemoryTileStore()

def zeros_tensor_func(ctx):
    return torch.zeros(10, 512, 512)  # (C, H, W)

base_window = TensorWindow((10, 512, 512))
base = tile_store.get_or_create("my_tensor", (10, None, None), zeros_tensor_func, base_window)

# Define an offset window for the dependent tensor
offset_window = TensorWindow((10, 512, 512), offset=(0, -256, -256))

# The function receives the upstream window directly (already sliced)
# now prev is a list of up to 4 tensors
def inc_func(ctx, prev):
    # return a list of the same size
    prev_stack = torch.stack(prev)
    return [p for p in (prev_stack + 1)]

dep = tile_store.get_or_create(
    "my_second_tensor",
    (10, None, None),
    inc_func,
    offset_window,
    args=(base,),
    args_windows=(offset_window,),
    batch_size=4
)

out = dep[:, 0:512, 0:512]  # ones

Important Notes

  1. Deterministic f: Your function must be deterministic—results are cached assuming f is pure.
  2. Create via TileStore: Construct tensors with tile_store.get_or_create(...). Direct construction of InfiniteTensor is not supported.
  3. Avoid manual slicing: Do not manually slice dependencies. Use args/args_windows so the framework manages slicing and dependencies.
  4. CPU Only: Outputs and inputs to f are always on the CPU. Returning tensors on other devices will raise errors.
  5. Window Size: Your function must return exactly the size specified in TensorWindow.
  6. Finite Dimensions: Non-infinite dimensions must fit in memory.

Example

Check out examples/blur.py for a complete example showing how to:

  • Process images larger than memory
  • Handle boundaries correctly
  • Chain multiple processing steps

License

MIT License - See LICENSE file for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

infinite_tensor-0.2.2.tar.gz (33.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

infinite_tensor-0.2.2-py3-none-any.whl (29.9 kB view details)

Uploaded Python 3

File details

Details for the file infinite_tensor-0.2.2.tar.gz.

File metadata

  • Download URL: infinite_tensor-0.2.2.tar.gz
  • Upload date:
  • Size: 33.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.13

File hashes

Hashes for infinite_tensor-0.2.2.tar.gz
Algorithm Hash digest
SHA256 b2e74f5dea3c75a1998e8e5c63b8d1b83bfb506298ac133f7a1db2faf4109f9e
MD5 bc64e8b527e77a2f5482b777958dcd8c
BLAKE2b-256 716f94b9e6c5ede7ac4de61448abd8d1e10aab19a7812ca3a4650fff6d25a44f

See more details on using hashes here.

File details

Details for the file infinite_tensor-0.2.2-py3-none-any.whl.

File metadata

File hashes

Hashes for infinite_tensor-0.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 0a8ee4a0ac9694a780bedddd0475f58be8b6a6ab97e07ae39a396aa68860946d
MD5 b7c2719819d2e630cf263044486254bc
BLAKE2b-256 8963c135433030c9b05b2ae05becbf01ca1a068440f1320a13c57eedcabcf4b0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page