Skip to content

daohhuynh/viper

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

VIPER (Voltage Imaging Processing Execution Routines)

High-throughput out-of-core quantitative pipeline for terabyte-scale time-series processing.

VIPER is an offline quantitative batch-processing engine engineered to ingest, register, and extract signal traces from massive optical datasets. Built to operate under strict memory constraints, the system bypasses standard RAM limits by orchestrating out-of-core memory mapping, GPU-accelerated tensor dispatch, and regularized linear algebra. While not a low-latency execution system, VIPER is architected identically to an overnight quantitative research pipeline, prioritizing deterministic memory footprints, zero-copy data ingress, and numerical stability when handling highly correlated, near-singular real-world data.

Critical Path and Data Flow

The pipeline executes a strict multi-stage transformation from raw video to serialized quantitative traces.

  1. Ingress: Multi-format video ingestion (.tif, .avi, .tiff stacks) is mapped directly to Zarr memory-mapped arrays to ensure a zero-copy access pattern.
  2. Processing Pipeline: Data flows through import, subpixel registration via Fourier Phase Correlation, neural segmentation via Cellpose CNN, and finally trace extraction utilizing SVD and matched filtering.
  3. Egress: Final quantitative states are serialized out to Zarr chunked arrays and .mat/.npy formats.

Because this is a batch-oriented research pipeline, network I/O and sockets are intentionally bypassed in favor of localized, high-throughput disk-to-GPU data streams. Routing logic relies on multiprocessing-based parallelism, explicitly capping subprocess.Popen() worker pools at exactly 12 cores to maximize throughput while avoiding Non-Uniform Memory Access (NUMA) CPU penalties.

Memory and Cache Architecture

Standard Python data science libraries implicitly allocate to the heap, which causes fatal Out-Of-Memory crashes when processing 2.5GB to terabyte-scale datasets. VIPER explicitly manages memory to maintain a flat allocation profile.

  • Zero-Copy Ingress and Heap Bypass: Data is ingested using zarr.open(..., mode='a'). By utilizing direct OS-level mmap calls, the pipeline eliminates heap allocation on the read path. The OS page cache acts as an implicit memory pool.
  • Cache-Line Optimizations and Rechunking: Initial ingestion pre-allocates arrays using a (1, n, m) Struct-of-Arrays layout. This single-frame chunking optimizes sequential temporal access and maintains spatial locality for row-major iteration. For spatial extraction, the system utilizes the rechunker library to transform the data to a (t, 1, 1) layout. This is achieved via an intermediate temporary store and an atomic swap, ensuring cache locality without redundant data duplication.
  • GPU Memory Pooling: To prevent allocation spikes and fragmentation during heavy FFT workloads, VIPER hooks directly into the CuPy memory pool. Blocks are manually recycled using mempool.free_all_blocks() after processing each 1GB data chunk, minimizing cudaMalloc overhead.

Quantitative Math and Numerical Stability

Real-world optical data is inherently noisy. Applying standard linear algebra directly results in algorithm collapse due to ill-conditioned matrices. VIPER implements explicit mathematical stabilizers derived from academic literature.

  • Regularized SVD Background Subtraction: The background extraction module utilizes Dask for chunked Singular Value Decomposition on the top 8 components, operating at $O(\min(t, p)^2 \cdot \max(t, p))$. To prevent near-singular Gram matrix instability during inversion, the system applies Tikhonov regularization (ridge regression) with a damping parameter of $\lambda = 0.01$. The inversion follows the stabilized formula: $$b = (U^T U + \lambda||U||_F^2 I)^{-1}$$
  • Subpixel Registration (Guizar-Sicairos 2008): Registration operates at $O(n \cdot m \log(n \cdot m))$ per frame. To achieve 1/200th pixel precision without the memory overhead of zero-padding, the system utilizes an upsampled DFT via matrix multiplication with an upsampling factor of 200.
  • Periodic-Smooth Decomposition (Moisan 2011): To remove low-frequency drift without introducing edge artifacts, the system utilizes a Fourier-domain division model. The formula applied is: $$s[q,r] = \frac{\hat{v}[q,r]}{2\cos(2\pi q/M) + 2\cos(2\pi r/N) - 4}$$ Singularity handling is strictly hardcoded (den[den==0] = 1) at the DC component to prevent division-by-zero runtime exceptions.
  • Trace Extraction and Filtering: Trace extraction maximizes Signal-to-Noise Ratio in the presence of colored noise by utilizing Welch spectral estimation for pre-whitening. The spatial footprint refinement employs an LSMR sparse least-squares solver operating at $O(k \cdot n \cdot m)$, utilizing a damping parameter of 0.01 to mirror L2 regularization.

Hardware and CPU Mechanics

  • GPU Acceleration: The pipeline offloads heavy tensor math to CuPy. FFT operations leverage the highly optimized cuFFT library, while 2D convolutions utilize CUDA kernels (Winograd or FFT-based). Element-wise operations like the periodic-smooth decomposition use custom written CUDA kernels for cp.cos() and cp.divide().
  • Floating-Point Precision: To prevent floating-point accumulation errors during massive phase correlation loops, all Fourier operations are strictly cast to double precision (cp.float64). Conversely, raw data is maintained in single precision (uint16 or float32) to balance VRAM limits and memory bandwidth.
  • SIMD and Branchless Logic: While Python abstracts explicit branchless control flow, the underlying NumPy C-backend utilizes Conditional Move (CMOV) instructions implicitly. Similarly, SIMD vectorization is handled implicitly via Intel MKL or OpenBLAS, enabling AVX2 and AVX-512 hardware acceleration on modern CPUs when GPU fallback is required.

Scale and Throughput

The architecture is explicitly tuned for high-throughput batch execution.

  • Data Volumes: A typical raw dataset consisting of 10,000 frames at 512x512 resolution consumes approximately 2.5GB. VIPER splits this into strict 1GB processing chunks to ensure it fits entirely within consumer GPU VRAM without swapping.
  • Execution Speed: Offloading the registration mathematics to the GPU yields a 10x to 100x latency reduction compared to CPU-bound NumPy FFTs, dropping processing times to roughly 10-50 milliseconds per 512x512 frame. Trace extraction processes 60-second epochs simultaneously, handling 30,000 frames per epoch at a 500Hz sampling rate.
  • I/O Latency: By implementing memory-mapped I/O and eliminating memory copy overhead, data loading operations are executed 2x to 5x faster than loading entire datasets directly into RAM.

About

High-performance offline pipeline for Voltage Imaging processing. Optimized for Apple Silicon (MPS) with out-of-core memory management.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages