In this section, we discuss implementation details of our batched QR kernel and compare it with other implementations from the MAGMA 2.2 [@tnld10] and CUBLAS 8 [@nvidia-cublas] libraries.

Implementation
--------------

One benefit of the Householder algorithm is that the application of reflectors to the trailing matrix (line \[alg:qr:trailing\_update\] of the algorithm) can be blocked together and expressed as a matrix-matrix multiplication (Level 3 BLAS) instead of multiple matrix-vector multiplications (Level 2 BLAS). The increased arithmetic intensity typically allows performance to improve when the trailing matrix is large. However, for small matrix blocks, the overhead of generating the blocked reflectors from their vector form as well as the lower performance of the matrix-matrix multiplication for small matrices hinder performance. We can obtain better performance by applying multiple reflectors in their vector form and performing the transpose matrix-vector multiplication efficiently within a thread block [@caqr_anderson]. First, we perform the regular factorization on a column block $P$ (called a panel). The entire panel is stored in registers, with each thread storing one row of the panel, and the transpose matrix-vector product is computed using a series of reductions using shared memory and warp shuffles [@warp_shfl] which allow threads within a warp to read 