memory consumption, where potentially only a few warps will be active in a multiprocessor. Instead, we exploit the inherent parallelism of the one-sided Jacobi to assign a warp to a pair of columns, i.e., there are $n/2$ warps processing an $m \times n$ matrix stored in shared memory. There are a total of $n(n-1)/2$ pairs of columns, so we must generate all pairings in $n-1$ steps, with each step processing $n/2$ pairs in parallel. There are many ways of generating these pairs, including round robin, odd-even, and ring ordering [@parosbj_zhou; @ZHOU19971]. We implement the round robin ordering using shared memory to keep track of the column indexes of the pairs with the first warp in the block responsible for updating the index list after each step. Figure \[fig:round\_robin\] shows this ordering for a matrix with 8 columns. When the number of matrix rows exceeds the size of the warp, the thread-per-row assignment no longer allows us to use fast warp reductions, which would force us to use even more resources, as the reductions would now have to be done in shared memory. Instead, we assign multiple rows to a thread, serializing a portion of the reduction over those rows until 