Consider the example in Fig. \[fig:step4\] again, the first transformation would be $\boldsymbol{Q}^*_{(8,1)}$, then $\boldsymbol{Q}^*_{(7,1)}$, $\boldsymbol{Q}^*_{(6,1)}$, and finally $\boldsymbol{Q}^*_{(5,1)}$. It is obvious that from one transformation to the next, the rows of $\boldsymbol{X}_\text{local}$ modified by the transformation are shifted upward by one row. This is also seen in Fig. \[fig:step4\], where $\boldsymbol{Q}^*_{(8,1)}$ modifies the 4$^\text{th}$ to 7$^\text{th}$ rows of $\boldsymbol{X}_\text{local}$, $\boldsymbol{Q}^*_{(7,1)}$ modifies the 3$^\text{rd}$ to 6$^\text{th}$ rows of $\boldsymbol{X}_\text{local}$, and so forth. Each individual $\boldsymbol{Q}^*_{(i,j)}$ actually only modifies $b$ rows of $\boldsymbol{X}_\text{local}$.

In order to map this local computation to the GPU cores, we choose a 1D block grid with a 1D thread grid within each block. The CUDA kernel is launched with $N_C$ blocks and $b$ threads, so that each block works on an eigenvector, and each thread works on an element of this eigenvector. Specifically, the Householder transformations are applied to $\boldsymbol{X}_\text{local}$ as follows:

1.  Copy $\boldsymbol{X}_\text{local}$, as well as all $\boldsymbol{v}$ and $\tau$ that ever update $\boldsymbol{X}_\text{local}$, from CPU to GPU. Each GPU block is responsible for one column of $\boldsymbol{X}_\text{local}$, denoted as $\boldsymbol{x}$.

2.  Compute Eq. \[eq:kernel\] for the first Householder transformation.

    1.  Compute dot product $\boldsymbol{v}^* \boldsymbol{x}$. Only $b$ elements of $\boldsymbol{x}$ contribute to the 