|
4 | 4 | """ |
5 | 5 | Adjusted Circular Correlation (ACCorr) connectivity metric. |
6 | 6 |
|
7 | | -ACCorr computes the circular correlation between two phase time-series with |
8 | | -per-pair phase centering, providing a more accurate inter-brain synchrony |
9 | | -estimate than standard circular correlation (ccorr). |
10 | | -
|
11 | | -Reference: Zimmermann et al. (2024). *Imaging Neuroscience*, 2. |
| 7 | +ACCorr computes the circular correlation between two phase time-series |
| 8 | +with **per-pair** phase centering, providing a more accurate inter-brain |
| 9 | +synchrony estimate than standard circular correlation (ccorr). |
| 10 | +
|
| 11 | +See the ``ACCorr`` class for the public API; it supports a CPU |
| 12 | +``precompute`` strategy (vectorised numerator + loop denominator with |
| 13 | +pre-computed per-pair adjustments), a numba JIT backend, and PyTorch |
| 14 | +GPU/MPS backends. The torch implementation switches between a fully |
| 15 | +vectorised 5-D broadcast and a per-pair loop based on |
| 16 | +``ACCorr._VRAM_THRESHOLD`` — see that attribute's docstring. |
| 17 | +
|
| 18 | +References |
| 19 | +---------- |
| 20 | +Zimmermann, M., Schultz-Nielsen, K., Dumas, G., & Konvalinka, I. (2024). |
| 21 | +Arbitrary methodological decisions skew inter-brain synchronization |
| 22 | +estimates in hyperscanning-EEG studies. *Imaging Neuroscience*, 2. |
12 | 23 | https://doi.org/10.1162/imag_a_00350 |
13 | 24 |
|
14 | 25 | Credits |
@@ -211,9 +222,24 @@ def _compute_numba(self, complex_signal: np.ndarray, n_samp: int, |
211 | 222 |
|
212 | 223 | return con |
213 | 224 |
|
214 | | - # Memory threshold for vectorized denominator (bytes). If the 5D tensor |
215 | | - # (E, F, C, C, T) would exceed this, fall back to the loop-based approach. |
216 | 225 | _VRAM_THRESHOLD = 2 * 1024**3 # 2 GB |
| 226 | + """ |
| 227 | + Memory threshold (bytes) for the vectorised torch denominator path. |
| 228 | +
|
| 229 | + Notes |
| 230 | + ----- |
| 231 | + The torch implementation prefers a fully-vectorised broadcast over the |
| 232 | + intermediate 5-D tensor of shape ``(n_epochs, n_freq, n_channels, |
| 233 | + n_channels, n_samples)`` for the per-pair phase centering. When the |
| 234 | + estimated tensor size in bytes exceeds this threshold, ``_compute_torch`` |
| 235 | + falls back to a per-pair loop on the same device (CPU / MPS / CUDA). |
| 236 | +
|
| 237 | + The 2 GB default is sized to keep one such tensor comfortably under |
| 238 | + Apple-Silicon MPS and Quadro-class GPU memory budgets when the rest of |
| 239 | + the pipeline (data tensors, kernel state) is already resident — a 4 GB |
| 240 | + threshold can OOM on high-channel-count realistic_hd benchmarks. This |
| 241 | + value is empirical; re-derive if you change the upstream tensor layout. |
| 242 | + """ |
217 | 243 |
|
218 | 244 | def _compute_torch(self, complex_signal: np.ndarray, n_samp: int, |
219 | 245 | transpose_axes: tuple) -> np.ndarray: |
|
0 commit comments