This example illustrates the use of hipSOLVER to compute the QR factorization of a matrix
-
$Q$ is an$m \times m$ unitary matrix, i.e.$Q^{-1} = Q^H$ -
$R$ is an$m \times n$ upper (or right) triangular matrix, i.e. all entries below the diagonal are zero.
In general, a rectangular matrix
In the general case hipSOLVER calculates
The calculated solution is verified by computing the root mean square of the elements in
- Declare and initialize variables for the in- and output matrix.
- Initialize the matrix on the host.
- Allocate device memory and copy the matrix to the device.
- Create a hipSOLVER handle and set up the working space needed for the QR factorization functions.
- Compute the first step of the QR factorization using
hipsolverDgeqrf
. - Compute the matrix Q with the householder vectors stored in d_A and the scaling factors in d_tau using
hipsolverDorgqr
. - Validate the result by calculating the root mean square of the elements in
$Q^T Q - I$ using hipBLAS. - Free device memory and handles.
-
hipSOLVER is initialized by calling
hipsolverCreate(hipsolverHandle_t*)
and it is terminated by callinghipsolverDestroy(hipsolverHandle_t)
. -
hipsolver[SDCZ]geqrf
computes the QR factorization of a$m \times n$ matrix$A$ . The results of$Q$ and$R$ are stored in place of$A$ . The orthogonal matrix$Q$ is not explicitly calculated, it is stored using householder vectors, which can be used to explicitly calculate$Q$ withhipsolver[SDCZ]orgqr
. Depending on the character matched in[SDCZ]
, the QR factorization can be obtained with different precisions:-
S
(single-precision:float
) -
D
(double-precision:double
) -
C
(single-precision complex:hipFloatComplex
) -
Z
(double-precision complex:hipDoubleComplex
).
In this example the double-precision variant
hipsolverDgeqrf
is used. Its input parameters are:hipsolverHandle_t handle
-
int m
number of rows of$A$ -
int n
number of columns of$A$ -
double *A
pointer to matrix$A$ -
int lda
leading dimension of matrix$A$ -
double *tau
vector that stores the scaling factors for the householder vectors. -
double *work
memory for working space used by the function -
int lwork
size of working space -
int *devInfo
status report of the function. The QR factorization is successful if the value pointed to by devInfo is 0. When using cuSOLVER as backend, if the value is a negative integer$-i$ , then the i-th parameter ofhipsolverDgeqrf
is wrong. The return type ishipsolverStatus_t
.
-
-
hipsolver[SDCZ]geqrf_bufferSize
calculates the required size of the working space forhipsolver[SDCZ]geqrf
. The used type has to match the actual solver function. The input parameters forhipsolverDgeqrf_bufferSize
are:hipsolverHandle_t handle
-
int m
number of rows of$A$ -
int n
number of columns of$A$ -
double *A
pointer to matrix$A$ -
int lda
leading dimension of matrix$A$ -
int *lwork
returns the size of the working space required The return type ishipsolverStatus_t
.
-
hipsolver[SD]orgqr
computes the orthogonal matrix$Q$ from the householder vectors, as stored in$A$ , and the corresponding scaling factors as stored in tau, both as returned byhipsolver[SD]geqrf
. In the case of complex matrices, the functionhipsolver[CZ]ungqr
has to be used. In this example the double-precision varianthipsolverDorgqr
is used. Its input parameters are:hipsolverHandle_t handle
-
int m
number of rows of matrix$Q$ -
int n
number of columns of matrix$Q$ ($m \geq n \gt 0$ ) -
int k
number of elementary reflections whose product defines the matrix$Q$ ($n \geq k \geq 0$ ) -
double *A
matrix containing the householder vectors -
int lda
leading dimension of$A$ -
double *tau
vector that stores the scaling factors for the householder vectors -
double *work
memory for working space used by the function -
int lwork
size of working space -
int *devInfo
status report of the function. The computation of$Q$ is successful if the value pointed to by devInfo is 0. When using cuSOLVER as backend, if the value is a negative integer$-i$ , then the i-th parameter ofhipsolverDorgqr
is wrong. The return type ishipsolverStatus_t
.
-
hipsolver[SD]orgqr_bufferSize
calculates the required size of the working space forhipsolver[SD]orgqr
. The used type has to match the actual solver function. The input parameters forhipsolverDorgqr_bufferSize
are:hipsolverHandle_t handle
-
int m
number of rows of matrix$Q$ -
int n
number of columns of matrix$Q$ -
int k
number of elementary reflection -
double *A
matrix containing the householder vectors -
int lda
leading dimension of$A$ -
double *tau
vector that stores the scaling factors for the householder vectors -
int *lwork
returns the size of the working space required The return type ishipsolverStatus_t
.
hipBLAS is used to validate the solution. To verify that hipblasDgemm
and the root mean square of the elements of that result is calculated using hipblasDnrm2
. hipblasDgemm
is showcased in the gemm_strided_batched example.
hipblasDnrm2
calculates the euclidean norm of a vector. In this example the root mean square of the elements in a matrix is calculated by pretending it to be a vector and calculating its euclidean norm, then dividing it by the number of elements in the matrix.
Its input parameters are:
- hipblasHandle_t handle
- int n
number of elements in x
- double *x
device pointer storing vector x
- int incx
stride between consecutive elements of x
- double *result
resulting norm
- The
hipblasPointerMode_t
type controls whether scalar parameters must be allocated on the host (HIPBLAS_POINTER_MODE_HOST
) or on the device (HIPBLAS_POINTER_MODE_DEVICE
). It is set by usinghipblasSetPointerMode
.
hipsolverCreate
hipsolverDestroy
hipsolverDgeqrf
hipsolverDgeqrf_bufferSize
hipsolverDorgqr
hipsolverDorgqr_bufferSize
hipsolverHandle_t
hipblasCreate
hipblasDestroy
hipblasDgemm
hipblasDnrm2
hipblasHandle_t
HIPBLAS_OP_N
HIPBLAS_OP_T
HIPBLAS_POINTER_MODE_HOST
hipblasSetPointerMode
hipFree
hipMalloc
hipMemcpy
hipMemcpyHostToDevice
hipMemcpyDeviceToHost