zunmlq_param.c 13.6 KB
Newer Older
1
/**
2 3
 *
 * @file zunmlq_param.c
4
 *
Mathieu Faverge's avatar
Mathieu Faverge committed
5 6
 * @copyright 2009-2014 The University of Tennessee and The University of
 *                      Tennessee Research Foundation. All rights reserved.
Mathieu Faverge's avatar
Mathieu Faverge committed
7
 * @copyright 2012-2018 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
8
 *                      Univ. Bordeaux. All rights reserved.
9
 *
10
 ***
11
 *
12
 * @brief Chameleon zunmlq_param wrappers
13
 *
Mathieu Faverge's avatar
Mathieu Faverge committed
14
 * @version 1.0.0
15
 * @author Mathieu Faverge
BOUCHERIE Raphael's avatar
BOUCHERIE Raphael committed
16 17
 * @author Raphael Boucherie
 * @date 2017-05-17
18 19
 * @precisions normal z -> s d c
 *
20
 */
21 22 23 24 25
#include "control/common.h"

/**
 *******************************************************************************
 *
26
 * @ingroup CHAMELEON_Complex64_t
27
 *
28
 *  CHAMELEON_zunmlq_param - Overwrites the general complex M-by-N matrix C with
29 30 31 32 33 34 35 36 37 38
 *
 *                  SIDE = 'L'     SIDE = 'R'
 *  TRANS = 'N':      Q * C          C * Q
 *  TRANS = 'C':      Q**H * C       C * Q**H
 *
 *  where Q is a complex unitary matrix defined as the product of k
 *  elementary reflectors
 *
 *        Q = H(1) H(2) . . . H(k)
 *
39 40
 *  as returned by CHAMELEON_zgeqrf. Q is of order M if SIDE = ChamLeft
 *  and of order N if SIDE = ChamRight.
41 42 43
 *
 *******************************************************************************
 *
BOUCHERIE Raphael's avatar
BOUCHERIE Raphael committed
44 45 46
 * @param[in] qrtree
 *          The tree used for the factorization
 *
47 48
 * @param[in] side
 *          Intended usage:
49 50
 *          = ChamLeft:  apply Q or Q**H from the left;
 *          = ChamRight: apply Q or Q**H from the right.
51 52 53
 *
 * @param[in] trans
 *          Intended usage:
54 55
 *          = ChamNoTrans:   no transpose, apply Q;
 *          = ChamConjTrans: conjugate transpose, apply Q**H.
56 57 58 59 60 61 62 63 64
 *
 * @param[in] M
 *          The number of rows of the matrix C. M >= 0.
 *
 * @param[in] N
 *          The number of columns of the matrix C. N >= 0.
 *
 * @param[in] K
 *          The number of rows of elementary tile reflectors whose product defines the matrix Q.
65 66
 *          If side == ChamLeft,  M >= K >= 0.
 *          If side == ChamRight, N >= K >= 0.
67 68
 *
 * @param[in] A
69
 *          Details of the LQ factorization of the original matrix A as returned by CHAMELEON_zgelqf.
70 71 72 73
 *
 * @param[in] LDA
 *          The leading dimension of the array A. LDA >= max(1,K).
 *
BOUCHERIE Raphael's avatar
BOUCHERIE Raphael committed
74
 * @param[in] descTS
75
 *          Auxiliary factorization data, computed by CHAMELEON_zgelqf.
BOUCHERIE Raphael's avatar
BOUCHERIE Raphael committed
76 77
 *
 * @param[in] descTT
78
 *          Auxiliary factorization data, computed by CHAMELEON_zgelqf.
79 80 81 82 83 84 85 86 87 88
 *
 * @param[in,out] C
 *          On entry, the M-by-N matrix C.
 *          On exit, C is overwritten by Q*C or Q**H*C.
 *
 * @param[in] LDC
 *          The leading dimension of the array C. LDC >= max(1,M).
 *
 *******************************************************************************
 *
89 90
 * @retval CHAMELEON_SUCCESS successful exit
 * @retval <0 if -i, the i-th argument had an illegal value
91 92 93
 *
 *******************************************************************************
 *
94 95 96 97 98 99
 * @sa CHAMELEON_zunmlq_param_Tile
 * @sa CHAMELEON_zunmlq_param_Tile_Async
 * @sa CHAMELEON_cunmlq
 * @sa CHAMELEON_dormlq
 * @sa CHAMELEON_sormlq
 * @sa CHAMELEON_zgelqf
100
 *
101
 */
102 103 104 105
int CHAMELEON_zunmlq_param( const libhqr_tree_t *qrtree, cham_side_t side, cham_trans_t trans, int M, int N, int K,
                        CHAMELEON_Complex64_t *A, int LDA,
                        CHAM_desc_t *descTS, CHAM_desc_t *descTT,
                        CHAMELEON_Complex64_t *C, int LDC )
106 107 108
{
    int NB, An;
    int status;
Mathieu Faverge's avatar
Mathieu Faverge committed
109
    CHAM_context_t *chamctxt;
110 111 112 113
    RUNTIME_sequence_t *sequence = NULL;
    RUNTIME_request_t request = RUNTIME_REQUEST_INITIALIZER;
    CHAM_desc_t descAl, descAt;
    CHAM_desc_t descCl, descCt;
114

Mathieu Faverge's avatar
Mathieu Faverge committed
115 116 117
    chamctxt = chameleon_context_self();
    if (chamctxt == NULL) {
        chameleon_fatal_error("CHAMELEON_zunmlq_param", "CHAMELEON not initialized");
118
        return CHAMELEON_ERR_NOT_INITIALIZED;
119 120
    }

121
    if (side == ChamLeft)
122 123 124 125 126
        An = M;
    else
        An = N;

    /* Check input arguments */
127
    if ((side != ChamLeft) && (side != ChamRight)) {
Mathieu Faverge's avatar
Mathieu Faverge committed
128
        chameleon_error("CHAMELEON_zunmlq_param", "illegal value of side");
129 130
        return -1;
    }
131
    if ((trans != ChamConjTrans) && (trans != ChamNoTrans)){
Mathieu Faverge's avatar
Mathieu Faverge committed
132
        chameleon_error("CHAMELEON_zunmlq_param", "illegal value of trans");
133 134 135
        return -2;
    }
    if (M < 0) {
Mathieu Faverge's avatar
Mathieu Faverge committed
136
        chameleon_error("CHAMELEON_zunmlq_param", "illegal value of M");
137 138 139
        return -3;
    }
    if (N < 0) {
Mathieu Faverge's avatar
Mathieu Faverge committed
140
        chameleon_error("CHAMELEON_zunmlq_param", "illegal value of N");
141 142 143
        return -4;
    }
    if ((K < 0) || (K > An)) {
Mathieu Faverge's avatar
Mathieu Faverge committed
144
        chameleon_error("CHAMELEON_zunmlq_param", "illegal value of K");
145 146 147
        return -5;
    }
    if (LDA < chameleon_max(1, K)) {
Mathieu Faverge's avatar
Mathieu Faverge committed
148
        chameleon_error("CHAMELEON_zunmlq_param", "illegal value of LDA");
149 150 151
        return -7;
    }
    if (LDC < chameleon_max(1, M)) {
Mathieu Faverge's avatar
Mathieu Faverge committed
152
        chameleon_error("CHAMELEON_zunmlq_param", "illegal value of LDC");
153 154 155 156 157
        return -10;
    }
    /* Quick return - currently NOT equivalent to LAPACK's:
     * CALL DLASET( 'Full', MAX( M, N ), NRHS, ZERO, ZERO, C, LDC ) */
    if (chameleon_min(M, chameleon_min(N, K)) == 0)
158
        return CHAMELEON_SUCCESS;
159 160

    /* Tune NB & IB depending on M, N & NRHS; Set NBNB */
Mathieu Faverge's avatar
Mathieu Faverge committed
161
    status = chameleon_tune(CHAMELEON_FUNC_ZGELS, M, K, N);
162
    if (status != CHAMELEON_SUCCESS) {
Mathieu Faverge's avatar
Mathieu Faverge committed
163
        chameleon_error("CHAMELEON_zunmlq_param", "chameleon_tune() failed");
164 165 166 167
        return status;
    }

    /* Set MT, NT & NTRHS */
168
    NB   = CHAMELEON_NB;
Mathieu Faverge's avatar
Mathieu Faverge committed
169
    chameleon_sequence_create( chamctxt, &sequence );
170

171
    /* Submit the matrix conversion */
Mathieu Faverge's avatar
Mathieu Faverge committed
172
    chameleon_zlap2tile( chamctxt, &descAl, &descAt, ChamDescInput, ChamUpper,
173
                     A, NB, NB, LDA, An, K, An, sequence, &request );
Mathieu Faverge's avatar
Mathieu Faverge committed
174
    chameleon_zlap2tile( chamctxt, &descCl, &descCt, ChamDescInout, ChamUpperLower,
175
                     C, NB, NB, LDC, N, M,  N, sequence, &request );
176 177

    /* Call the tile interface */
178
    CHAMELEON_zunmlq_param_Tile_Async( qrtree, side, trans, &descAt, descTS, descTT, &descCt, sequence, &request );
179

Mathieu Faverge's avatar
Mathieu Faverge committed
180
    /* Submit the matrix conversion back */
Mathieu Faverge's avatar
Mathieu Faverge committed
181
    chameleon_ztile2lap( chamctxt, &descAl, &descAt,
182
                     ChamDescInput, ChamUpper, sequence, &request );
Mathieu Faverge's avatar
Mathieu Faverge committed
183
    chameleon_ztile2lap( chamctxt, &descCl, &descCt,
184 185 186
                     ChamDescInout, ChamUpperLower, sequence, &request );
    CHAMELEON_Desc_Flush( descTS, sequence );
    CHAMELEON_Desc_Flush( descTT, sequence );
Mathieu Faverge's avatar
Mathieu Faverge committed
187

Mathieu Faverge's avatar
Mathieu Faverge committed
188
    chameleon_sequence_wait( chamctxt, sequence );
Mathieu Faverge's avatar
Mathieu Faverge committed
189

Mathieu Faverge's avatar
Mathieu Faverge committed
190
    /* Cleanup the temporary data */
Mathieu Faverge's avatar
Mathieu Faverge committed
191 192
    chameleon_ztile2lap_cleanup( chamctxt, &descAl, &descAt );
    chameleon_ztile2lap_cleanup( chamctxt, &descCl, &descCt );
193 194

    status = sequence->status;
Mathieu Faverge's avatar
Mathieu Faverge committed
195
    chameleon_sequence_destroy( chamctxt, sequence );
196 197 198 199 200 201
    return status;
}

/**
 *******************************************************************************
 *
202
 * @ingroup CHAMELEON_Complex64_t_Tile
203
 *
204
 *  CHAMELEON_zunmlq_param_Tile - overwrites the general M-by-N matrix C with Q*C, where Q is an orthogonal
205
 *  matrix (unitary in the complex case) defined as the product of elementary reflectors returned
206
 *  by CHAMELEON_zgelqf_Tile Q is of order M.
207 208 209 210 211 212
 *  All matrices are passed through descriptors. All dimensions are taken from the descriptors.
 *
 *******************************************************************************
 *
 * @param[in] side
 *          Intended usage:
213 214 215
 *          = ChamLeft:  apply Q or Q**H from the left;
 *          = ChamRight: apply Q or Q**H from the right.
 *          Currently only ChamLeft is supported.
216 217 218
 *
 * @param[in] trans
 *          Intended usage:
219 220 221
 *          = ChamNoTrans:   no transpose, apply Q;
 *          = ChamConjTrans: conjugate transpose, apply Q**H.
 *          Currently only ChamConjTrans is supported.
222 223
 *
 * @param[in] A
224
 *          Details of the LQ factorization of the original matrix A as returned by CHAMELEON_zgelqf.
225 226
 *
 * @param[in] T
227
 *          Auxiliary factorization data, computed by CHAMELEON_zgelqf.
228 229 230 231 232 233 234
 *
 * @param[in,out] C
 *          On entry, the M-by-N matrix C.
 *          On exit, C is overwritten by Q*C or Q**H*C.
 *
 *******************************************************************************
 *
235
 * @retval CHAMELEON_SUCCESS successful exit
236 237 238
 *
 *******************************************************************************
 *
239 240 241 242 243 244
 * @sa CHAMELEON_zunmlq_param
 * @sa CHAMELEON_zunmlq_param_Tile_Async
 * @sa CHAMELEON_cunmlq_Tile
 * @sa CHAMELEON_dormlq_Tile
 * @sa CHAMELEON_sormlq_Tile
 * @sa CHAMELEON_zgelqf_Tile
245
 *
246
 */
247 248
int CHAMELEON_zunmlq_param_Tile( const libhqr_tree_t *qrtree, cham_side_t side, cham_trans_t trans,
                             CHAM_desc_t *A, CHAM_desc_t *TS, CHAM_desc_t *TT, CHAM_desc_t *C )
249
{
Mathieu Faverge's avatar
Mathieu Faverge committed
250
    CHAM_context_t *chamctxt;
251 252
    RUNTIME_sequence_t *sequence = NULL;
    RUNTIME_request_t request = RUNTIME_REQUEST_INITIALIZER;
253 254
    int status;

Mathieu Faverge's avatar
Mathieu Faverge committed
255 256 257
    chamctxt = chameleon_context_self();
    if (chamctxt == NULL) {
        chameleon_fatal_error("CHAMELEON_zunmlq_param_Tile", "CHAMELEON not initialized");
258
        return CHAMELEON_ERR_NOT_INITIALIZED;
259
    }
Mathieu Faverge's avatar
Mathieu Faverge committed
260
    chameleon_sequence_create( chamctxt, &sequence );
261

262
    CHAMELEON_zunmlq_param_Tile_Async( qrtree, side, trans, A, TS, TT, C, sequence, &request );
263

264 265 266 267
    CHAMELEON_Desc_Flush( A, sequence );
    CHAMELEON_Desc_Flush( TS, sequence );
    CHAMELEON_Desc_Flush( TT, sequence );
    CHAMELEON_Desc_Flush( C, sequence );
Mathieu Faverge's avatar
Mathieu Faverge committed
268

Mathieu Faverge's avatar
Mathieu Faverge committed
269
    chameleon_sequence_wait( chamctxt, sequence );
270
    status = sequence->status;
Mathieu Faverge's avatar
Mathieu Faverge committed
271
    chameleon_sequence_destroy( chamctxt, sequence );
272 273 274 275 276 277
    return status;
}

/**
 *******************************************************************************
 *
278
 * @ingroup CHAMELEON_Complex64_t_Tile_Async
279
 *
280
 *  Non-blocking equivalent of CHAMELEON_zunmlq_param_Tile().
281 282 283 284 285 286 287 288 289 290 291 292 293 294
 *  May return before the computation is finished.
 *  Allows for pipelining of operations at runtime.
 *
 *******************************************************************************
 *
 * @param[in] sequence
 *          Identifies the sequence of function calls that this call belongs to
 *          (for completion checks and exception handling purposes).
 *
 * @param[out] request
 *          Identifies this function call (for exception handling purposes).
 *
 *******************************************************************************
 *
295 296 297 298 299 300
 * @sa CHAMELEON_zunmlq_param
 * @sa CHAMELEON_zunmlq_param_Tile
 * @sa CHAMELEON_cunmlq_Tile_Async
 * @sa CHAMELEON_dormlq_Tile_Async
 * @sa CHAMELEON_sormlq_Tile_Async
 * @sa CHAMELEON_zgelqf_Tile_Async
301
 *
302
 */
303 304 305
int CHAMELEON_zunmlq_param_Tile_Async( const libhqr_tree_t *qrtree, cham_side_t side, cham_trans_t trans,
                                   CHAM_desc_t *A, CHAM_desc_t *TS, CHAM_desc_t *TT, CHAM_desc_t *C,
                                   RUNTIME_sequence_t *sequence, RUNTIME_request_t *request )
306
{
Mathieu Faverge's avatar
Mathieu Faverge committed
307
    CHAM_context_t *chamctxt;
308
    CHAM_desc_t D, *Dptr = NULL;
309

Mathieu Faverge's avatar
Mathieu Faverge committed
310 311 312
    chamctxt = chameleon_context_self();
    if (chamctxt == NULL) {
        chameleon_fatal_error("CHAMELEON_zunmlq_param_Tile", "CHAMELEON not initialized");
313
        return CHAMELEON_ERR_NOT_INITIALIZED;
314 315
    }
    if (sequence == NULL) {
Mathieu Faverge's avatar
Mathieu Faverge committed
316
        chameleon_fatal_error("CHAMELEON_zunmlq_param_Tile", "NULL sequence");
317
        return CHAMELEON_ERR_UNALLOCATED;
318 319
    }
    if (request == NULL) {
Mathieu Faverge's avatar
Mathieu Faverge committed
320
        chameleon_fatal_error("CHAMELEON_zunmlq_param_Tile", "NULL request");
321
        return CHAMELEON_ERR_UNALLOCATED;
322 323
    }
    /* Check sequence status */
324 325
    if (sequence->status == CHAMELEON_SUCCESS) {
        request->status = CHAMELEON_SUCCESS;
Mathieu Faverge's avatar
Mathieu Faverge committed
326 327
    }
    else {
Mathieu Faverge's avatar
Mathieu Faverge committed
328
        return chameleon_request_fail(sequence, request, CHAMELEON_ERR_SEQUENCE_FLUSHED);
Mathieu Faverge's avatar
Mathieu Faverge committed
329
    }
330 331

    /* Check descriptors for correctness */
Mathieu Faverge's avatar
Mathieu Faverge committed
332 333 334
    if (chameleon_desc_check(A) != CHAMELEON_SUCCESS) {
        chameleon_error("CHAMELEON_zunmlq_param_Tile", "invalid first descriptor");
        return chameleon_request_fail(sequence, request, CHAMELEON_ERR_ILLEGAL_VALUE);
335
    }
Mathieu Faverge's avatar
Mathieu Faverge committed
336 337 338
    if (chameleon_desc_check(TS) != CHAMELEON_SUCCESS) {
        chameleon_error("CHAMELEON_zunmlq_param_Tile", "invalid second descriptor");
        return chameleon_request_fail(sequence, request, CHAMELEON_ERR_ILLEGAL_VALUE);
339
    }
Mathieu Faverge's avatar
Mathieu Faverge committed
340 341 342
    if (chameleon_desc_check(TT) != CHAMELEON_SUCCESS) {
        chameleon_error("CHAMELEON_zunmlq_param_Tile", "invalid third descriptor");
        return chameleon_request_fail(sequence, request, CHAMELEON_ERR_ILLEGAL_VALUE);
343
    }
Mathieu Faverge's avatar
Mathieu Faverge committed
344 345 346
    if (chameleon_desc_check(C) != CHAMELEON_SUCCESS) {
        chameleon_error("CHAMELEON_zunmlq_param_Tile", "invalid fourth descriptor");
        return chameleon_request_fail(sequence, request, CHAMELEON_ERR_ILLEGAL_VALUE);
347 348 349
    }
    /* Check input arguments */
    if (A->nb != A->mb || C->nb != C->mb) {
Mathieu Faverge's avatar
Mathieu Faverge committed
350 351
        chameleon_error("CHAMELEON_zunmlq_param_Tile", "only square tiles supported");
        return chameleon_request_fail(sequence, request, CHAMELEON_ERR_ILLEGAL_VALUE);
352
    }
353
    if ((side != ChamLeft) && (side != ChamRight)) {
Mathieu Faverge's avatar
Mathieu Faverge committed
354
        return chameleon_request_fail(sequence, request, CHAMELEON_ERR_ILLEGAL_VALUE);
355
    }
356
    if ((trans != ChamConjTrans) && (trans != ChamNoTrans)){
Mathieu Faverge's avatar
Mathieu Faverge committed
357
        return chameleon_request_fail(sequence, request, CHAMELEON_ERR_ILLEGAL_VALUE);
358 359 360
    }
    /* Quick return - currently NOT equivalent to LAPACK's:
     * CALL DLASET( 'Full', MAX( M, N ), NRHS, ZERO, ZERO, C, LDC ) */
361 362
    /*
     if (chameleon_min(M, chameleon_min(N, K)) == 0)
363
     return CHAMELEON_SUCCESS;
364
     */
365

BOUCHERIE Raphael's avatar
BOUCHERIE Raphael committed
366
#if defined(CHAMELEON_COPY_DIAG)
Mathieu Faverge's avatar
Mathieu Faverge committed
367
    {
368
        int m = chameleon_min(A->m, A->n);
Mathieu Faverge's avatar
Mathieu Faverge committed
369
        chameleon_zdesc_alloc(D, A->mb, A->nb, m, A->n, 0, 0, m, A->n, );
Mathieu Faverge's avatar
Mathieu Faverge committed
370 371
        Dptr = &D;
    }
BOUCHERIE Raphael's avatar
BOUCHERIE Raphael committed
372
#endif
Mathieu Faverge's avatar
Mathieu Faverge committed
373

374
    chameleon_pzunmlq_param( 1, qrtree, side, trans, A, C, TS, TT, Dptr, sequence, request );
Mathieu Faverge's avatar
Mathieu Faverge committed
375

376
    if ( Dptr != NULL ) {
377 378 379 380 381
        CHAMELEON_Desc_Flush( A, sequence );
        CHAMELEON_Desc_Flush( C, sequence );
        CHAMELEON_Desc_Flush( TS, sequence );
        CHAMELEON_Desc_Flush( TT, sequence );
        CHAMELEON_Desc_Flush( Dptr, sequence );
Mathieu Faverge's avatar
Mathieu Faverge committed
382
        chameleon_sequence_wait( chamctxt, sequence );
383
        chameleon_desc_destroy( Dptr );
Mathieu Faverge's avatar
Mathieu Faverge committed
384
    }
BOUCHERIE Raphael's avatar
BOUCHERIE Raphael committed
385
    (void)D;
386
    return CHAMELEON_SUCCESS;
387
}