In plain words: Each new value here multiplies the previous one and adds a number, so it must go one step at a time. Two sweep-and-add passes compute all values at once, finishing in log n steps and running n/log n times faster on n processors.
Abstract · Efficient Parallelization of a Ubiquitous Sequential Computation
We find a succinct expression for computing the sequence $x_t = a_t x_{t-1} + b_t$ in parallel with two prefix sums, given $t = (1, 2, \dots, n)$, $a_t \in \mathbb{R}^n$, $b_t \in \mathbb{R}^n$, and initial value $x_0 \in \mathbb{R}$. On $n$ parallel processors, the computation of $n$ elements incurs $\mathcal{O}(\log n)$ time and $\mathcal{O}(n)$ space. Sequences of this form are ubiquitous in science and engineering, making efficient parallelization useful for a vast number of applications. We implement our expression in software, test it on parallel hardware, and verify that it executes faster than sequential computation by a factor of $\frac{n}{\log n}$.
Franz A. Heinsen
arXiv:2311.06281 · cs.DS, cs.LG · submitted Oct 27, 2023 · updated Dec 27, 2023
abstract · pdf · html · Source code for replicating our results is available online at https://github.com/glassroom/heinsen_sequence
The following operator called `combine` works. It's associative over these tuples; the final result will be the final value of the second component. Altogether, this gives you O(n) work and O(log n) span, but using just a single parallel prefix kernel, which may be more efficient in practice.
For example, here's a C++ implementation: https://github.com/MPLLang/parallel-ml-bench/blob/main/cpp/l... And, here's an implementation in a functional language: https://github.com/MPLLang/parallel-ml-bench/blob/main/mpl/b...I'm pretty sure this generalizes, too, to abstract multiplications and additions in any field (at first glance, seems like it should but I haven't done the formal proof yet).
Anyway, it would be interesting to compare this against the solution in the arxiv paper.
----
EDIT: ah, good, this is already being discussed here: https://github.com/glassroom/heinsen_sequence/issues/1
And, for reference, I learned this algorithm from Guy Blelloch; see Sec 1.4.1 of https://www.cs.cmu.edu/~guyb/papers/Ble93.pdf