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 is a tool that lets you work with data that has one or more unbounded (infinite) dimensions. Instead of loading all data into memory at once, it:

  • Loads only the parts you need, when you need them
  • Processes data in manageable chunks (windows)

It works like a convolution, but supporting arbitrary functions, and acting on infinitely large images.

Internally, an InfiniteTensor divides the infinite dimensions into tiles stored in a TileStore. When you index a region, the system identifies which output windows intersect that region, invokes your function f on each needed window (optionally batched), and adds the result to the appropriate tiles. Future reads reuse cached data. No tile 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: Like a PyTorch tensor, but infinite

    • Has a size, like a normal tensor, but some dimensions can be None (Infinite)
    • Generated by a 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,
    chunk_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. 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.

2. 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. Create via TileStore: Construct tensors with tile_store.get_or_create(...). Direct construction of InfiniteTensor is not supported.
  2. Avoid manual slicing: Do not manually slice dependencies. Use args/args_windows so the framework manages slicing and dependencies.
  3. CPU Only: Outputs and inputs to f are always on the CPU. Returning tensors on other devices will raise errors.
  4. Window Size: Your function must return exactly the size specified in TensorWindow.
  5. 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

Troubleshooting

Common issues and solutions:

  1. Memory Issues:

    • Reduce window size
    • Reduce chunk size
    • Reinitialize the relevant TileStore if tiles need to be discarded
  2. Shape Mismatches:

    • Ensure your function returns exactly the window size
    • Check that window sizes match between dependent tensors
  3. Performance:

    • Adjust chunk size to balance memory use and processing overhead
    • Consider window overlap requirements carefully

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.1.tar.gz (30.3 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.1-py3-none-any.whl (27.1 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: infinite_tensor-0.2.1.tar.gz
  • Upload date:
  • Size: 30.3 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.1.tar.gz
Algorithm Hash digest
SHA256 2bcdfe46a795249cc9a2adf28a5f653c5f0d128a2c8888ee58b331ad4fa320c0
MD5 e05d3c2d4d97bf279d82f47c5bb37918
BLAKE2b-256 45cfc4b67e9629f8eb86ab462e5bff6cc9c10b175b36d56e80768b6b1b596ad1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for infinite_tensor-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 db57533048073b29e836c8f296cebd31d2f900822883786537bf0feb161dee03
MD5 9cd5c2900e1544701675d79bdddd54b1
BLAKE2b-256 6854055895d945427625532028efffa6ecf533461afb1b428a55735e730daa46

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