zunglq_param.c 11.4 KB
Newer Older
1
/**
2 3
 *
 * @file zunglq_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 zunglq_param wrappers
13
 *
BOUCHERIE Raphael's avatar
BOUCHERIE Raphael 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 29
 *  CHAMELEON_zunglq_param - Generates an M-by-N matrix Q with orthonormal rows, which is defined as the
 *  first M rows of a product of the elementary reflectors returned by CHAMELEON_zgelqf.
30 31 32
 *
 *******************************************************************************
 *
BOUCHERIE Raphael's avatar
BOUCHERIE Raphael committed
33 34 35
 * @param[in] qrtree
 *          The tree used for the factorization
 *
36 37 38 39 40 41 42 43 44 45 46
 * @param[in] M
 *          The number of rows of the matrix Q. M >= 0.
 *
 * @param[in] N
 *          The number of columns of the matrix Q. N >= M.
 *
 * @param[in] K
 *          The number of rows of elementary tile reflectors whose product defines the matrix Q.
 *          M >= K >= 0.
 *
 * @param[in] A
47
 *          Details of the LQ factorization of the original matrix A as returned by CHAMELEON_zgelqf.
48 49 50 51 52
 *
 * @param[in] LDA
 *          The leading dimension of the array A. LDA >= max(1,M).
 *
 * @param[in] descT
53
 *          Auxiliary factorization data, computed by CHAMELEON_zgelqf.
54 55 56 57 58 59 60 61 62
 *
 * @param[out] Q
 *          On exit, the M-by-N matrix Q.
 *
 * @param[in] LDQ
 *          The leading dimension of the array Q. LDQ >= max(1,M).
 *
 *******************************************************************************
 *
63 64
 * @retval CHAMELEON_SUCCESS successful exit
 * @retval CHAMELEON_SUCCESS <0 if -i, the i-th argument had an illegal value
65 66 67
 *
 *******************************************************************************
 *
68 69 70 71 72 73
 * @sa CHAMELEON_zunglq_param_Tile
 * @sa CHAMELEON_zunglq_param_Tile_Async
 * @sa CHAMELEON_cunglq
 * @sa CHAMELEON_dorglq
 * @sa CHAMELEON_sorglq
 * @sa CHAMELEON_zgelqf
74
 *
75
 */
76 77 78 79
int CHAMELEON_zunglq_param( const libhqr_tree_t *qrtree, int M, int N, int K,
                        CHAMELEON_Complex64_t *A, int LDA,
                        CHAM_desc_t *descTS, CHAM_desc_t *descTT,
                        CHAMELEON_Complex64_t *Q, int LDQ )
80 81 82
{
    int NB;
    int status;
Mathieu Faverge's avatar
Mathieu Faverge committed
83
    CHAM_context_t *chamctxt;
84 85 86 87
    RUNTIME_sequence_t *sequence = NULL;
    RUNTIME_request_t request = RUNTIME_REQUEST_INITIALIZER;
    CHAM_desc_t descAl, descAt;
    CHAM_desc_t descQl, descQt;
88

Mathieu Faverge's avatar
Mathieu Faverge committed
89 90 91
    chamctxt = chameleon_context_self();
    if (chamctxt == NULL) {
        chameleon_fatal_error("CHAMELEON_zunglq_param", "CHAMELEON not initialized");
92
        return CHAMELEON_ERR_NOT_INITIALIZED;
93 94 95
    }
    /* Check input arguments */
    if (M < 0) {
Mathieu Faverge's avatar
Mathieu Faverge committed
96
        chameleon_error("CHAMELEON_zunglq_param", "illegal value of M");
97 98 99
        return -1;
    }
    if (N < M) {
Mathieu Faverge's avatar
Mathieu Faverge committed
100
        chameleon_error("CHAMELEON_zunglq_param", "illegal value of N");
101 102 103
        return -2;
    }
    if (K < 0 || K > M) {
Mathieu Faverge's avatar
Mathieu Faverge committed
104
        chameleon_error("CHAMELEON_zunglq_param", "illegal value of K");
105 106 107
        return -3;
    }
    if (LDA < chameleon_max(1, M)) {
Mathieu Faverge's avatar
Mathieu Faverge committed
108
        chameleon_error("CHAMELEON_zunglq_param", "illegal value of LDA");
109 110 111
        return -5;
    }
    if (LDQ < chameleon_max(1, M)) {
Mathieu Faverge's avatar
Mathieu Faverge committed
112
        chameleon_error("CHAMELEON_zunglq_param", "illegal value of LDQ");
113 114 115 116 117
        return -8;
    }
    /* Quick return - currently NOT equivalent to LAPACK's:
     * CALL DLASET( 'Full', MAX( M, N ), NRHS, ZERO, ZERO, B, LDQ ) */
    if (chameleon_min(M, chameleon_min(N, K)) == 0)
118
        return CHAMELEON_SUCCESS;
119 120

    /* Tune NB & IB depending on M, N & NRHS; Set NBNB */
Mathieu Faverge's avatar
Mathieu Faverge committed
121
    status = chameleon_tune(CHAMELEON_FUNC_ZGELS, M, N, 0);
122
    if (status != CHAMELEON_SUCCESS) {
Mathieu Faverge's avatar
Mathieu Faverge committed
123
        chameleon_error("CHAMELEON_zunglq_param", "chameleon_tune() failed");
124 125 126 127
        return status;
    }

    /* Set NT */
128
    NB = CHAMELEON_NB;
129

Mathieu Faverge's avatar
Mathieu Faverge committed
130
    chameleon_sequence_create( chamctxt, &sequence );
131

132
    /* Submit the matrix conversion */
Mathieu Faverge's avatar
Mathieu Faverge committed
133
    chameleon_zlap2tile( chamctxt, &descAl, &descAt, ChamDescInput, ChamUpper,
134
                     A, NB, NB, LDA, N, K, N, sequence, &request );
Mathieu Faverge's avatar
Mathieu Faverge committed
135
    chameleon_zlap2tile( chamctxt, &descQl, &descQt, ChamDescInout, ChamUpperLower,
136
                     Q, NB, NB, LDQ, N, M, N, sequence, &request );
137 138

    /* Call the tile interface */
139
    CHAMELEON_zunglq_param_Tile_Async( qrtree, &descAt, descTS, descTT, &descQt, sequence, &request );
140

Mathieu Faverge's avatar
Mathieu Faverge committed
141
    /* Submit the matrix conversion back */
Mathieu Faverge's avatar
Mathieu Faverge committed
142
    chameleon_ztile2lap( chamctxt, &descAl, &descAt,
143
                     ChamDescInput, ChamUpper, sequence, &request );
Mathieu Faverge's avatar
Mathieu Faverge committed
144
    chameleon_ztile2lap( chamctxt, &descQl, &descQt,
145 146 147
                     ChamDescInout, ChamUpperLower, sequence, &request );
    CHAMELEON_Desc_Flush( descTS, sequence );
    CHAMELEON_Desc_Flush( descTT, sequence );
Mathieu Faverge's avatar
Mathieu Faverge committed
148

Mathieu Faverge's avatar
Mathieu Faverge committed
149
    chameleon_sequence_wait( chamctxt, sequence );
Mathieu Faverge's avatar
Mathieu Faverge committed
150

Mathieu Faverge's avatar
Mathieu Faverge committed
151
    /* Cleanup the temporary data */
Mathieu Faverge's avatar
Mathieu Faverge committed
152 153
    chameleon_ztile2lap_cleanup( chamctxt, &descAl, &descAt );
    chameleon_ztile2lap_cleanup( chamctxt, &descQl, &descQt );
154 155

    status = sequence->status;
Mathieu Faverge's avatar
Mathieu Faverge committed
156
    chameleon_sequence_destroy( chamctxt, sequence );
157 158 159 160 161 162
    return status;
}

/**
 *******************************************************************************
 *
163
 * @ingroup CHAMELEON_Complex64_t_Tile
164
 *
165 166
 * CHAMELEON_zunglq_param_Tile - Generates an M-by-N matrix Q with orthonormal rows, which is defined as the
 * first M rows of a product of the elementary reflectors returned by CHAMELEON_zgelqf.
167 168 169 170 171
 * All matrices are passed through descriptors. All dimensions are taken from the descriptors.
 *
 *******************************************************************************
 *
 * @param[in] A
172
 *          Details of the LQ factorization of the original matrix A as returned by CHAMELEON_zgelqf.
173 174
 *
 * @param[in] T
175
 *          Auxiliary factorization data, computed by CHAMELEON_zgelqf.
176 177 178 179 180 181
 *
 * @param[out] Q
 *          On exit, the M-by-N matrix Q.
 *
 *******************************************************************************
 *
182
 * @retval CHAMELEON_SUCCESS successful exit
183 184 185
 *
 *******************************************************************************
 *
186 187 188 189 190 191
 * @sa CHAMELEON_zunglq_param
 * @sa CHAMELEON_zunglq_param_Tile_Async
 * @sa CHAMELEON_cunglq_Tile
 * @sa CHAMELEON_dorglq_Tile
 * @sa CHAMELEON_sorglq_Tile
 * @sa CHAMELEON_zgelqf_Tile
192
 *
193
 */
194
int CHAMELEON_zunglq_param_Tile( const libhqr_tree_t *qrtree, CHAM_desc_t *A, CHAM_desc_t *TS, CHAM_desc_t *TT, CHAM_desc_t *Q )
195
{
Mathieu Faverge's avatar
Mathieu Faverge committed
196
    CHAM_context_t *chamctxt;
197 198
    RUNTIME_sequence_t *sequence = NULL;
    RUNTIME_request_t request = RUNTIME_REQUEST_INITIALIZER;
199 200
    int status;

Mathieu Faverge's avatar
Mathieu Faverge committed
201 202 203
    chamctxt = chameleon_context_self();
    if (chamctxt == NULL) {
        chameleon_fatal_error("CHAMELEON_zunglq_param_Tile", "CHAMELEON not initialized");
204
        return CHAMELEON_ERR_NOT_INITIALIZED;
205
    }
Mathieu Faverge's avatar
Mathieu Faverge committed
206
    chameleon_sequence_create( chamctxt, &sequence );
207

208
    CHAMELEON_zunglq_param_Tile_Async( qrtree, A, TS, TT, Q, sequence, &request );
209

210 211 212 213
    CHAMELEON_Desc_Flush( A, sequence );
    CHAMELEON_Desc_Flush( TS, sequence );
    CHAMELEON_Desc_Flush( TT, sequence );
    CHAMELEON_Desc_Flush( Q, sequence );
Mathieu Faverge's avatar
Mathieu Faverge committed
214

Mathieu Faverge's avatar
Mathieu Faverge committed
215
    chameleon_sequence_wait( chamctxt, sequence );
216
    status = sequence->status;
Mathieu Faverge's avatar
Mathieu Faverge committed
217
    chameleon_sequence_destroy( chamctxt, sequence );
218 219 220 221 222 223
    return status;
}

/**
 *******************************************************************************
 *
224
 * @ingroup CHAMELEON_Complex64_t_Tile_Async
225
 *
226
 *  Non-blocking equivalent of CHAMELEON_zunglq_param_Tile().
227 228 229 230 231 232 233 234 235 236 237 238 239 240
 *  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).
 *
 *******************************************************************************
 *
241 242 243 244 245 246
 * @sa CHAMELEON_zunglq_param
 * @sa CHAMELEON_zunglq_param_Tile
 * @sa CHAMELEON_cunglq_Tile_Async
 * @sa CHAMELEON_dorglq_Tile_Async
 * @sa CHAMELEON_sorglq_Tile_Async
 * @sa CHAMELEON_zgelqf_Tile_Async
247
 *
248
 */
249 250
int CHAMELEON_zunglq_param_Tile_Async( const libhqr_tree_t *qrtree, CHAM_desc_t *A, CHAM_desc_t *TS, CHAM_desc_t *TT, CHAM_desc_t *Q,
                                   RUNTIME_sequence_t *sequence, RUNTIME_request_t *request )
251
{
Mathieu Faverge's avatar
Mathieu Faverge committed
252
    CHAM_context_t *chamctxt;
253
    CHAM_desc_t D, *Dptr = NULL;
254

Mathieu Faverge's avatar
Mathieu Faverge committed
255 256 257
    chamctxt = chameleon_context_self();
    if (chamctxt == NULL) {
        chameleon_fatal_error("CHAMELEON_zunglq_param_Tile", "CHAMELEON not initialized");
258
        return CHAMELEON_ERR_NOT_INITIALIZED;
259 260
    }
    if (sequence == NULL) {
Mathieu Faverge's avatar
Mathieu Faverge committed
261
        chameleon_fatal_error("CHAMELEON_zunglq_param_Tile", "NULL sequence");
262
        return CHAMELEON_ERR_UNALLOCATED;
263 264
    }
    if (request == NULL) {
Mathieu Faverge's avatar
Mathieu Faverge committed
265
        chameleon_fatal_error("CHAMELEON_zunglq_param_Tile", "NULL request");
266
        return CHAMELEON_ERR_UNALLOCATED;
267 268
    }
    /* Check sequence status */
269 270
    if (sequence->status == CHAMELEON_SUCCESS) {
        request->status = CHAMELEON_SUCCESS;
Mathieu Faverge's avatar
Mathieu Faverge committed
271 272
    }
    else {
Mathieu Faverge's avatar
Mathieu Faverge committed
273
        return chameleon_request_fail(sequence, request, CHAMELEON_ERR_SEQUENCE_FLUSHED);
Mathieu Faverge's avatar
Mathieu Faverge committed
274
    }
275 276

    /* Check descriptors for correctness */
Mathieu Faverge's avatar
Mathieu Faverge committed
277 278 279
    if (chameleon_desc_check(A) != CHAMELEON_SUCCESS) {
        chameleon_error("CHAMELEON_zunglq_param_Tile", "invalid first descriptor");
        return chameleon_request_fail(sequence, request, CHAMELEON_ERR_ILLEGAL_VALUE);
280
    }
Mathieu Faverge's avatar
Mathieu Faverge committed
281 282 283
    if (chameleon_desc_check(TS) != CHAMELEON_SUCCESS) {
        chameleon_error("CHAMELEON_zunglq_param_Tile", "invalid second descriptor");
        return chameleon_request_fail(sequence, request, CHAMELEON_ERR_ILLEGAL_VALUE);
284
    }
Mathieu Faverge's avatar
Mathieu Faverge committed
285 286 287
    if (chameleon_desc_check(TT) != CHAMELEON_SUCCESS) {
        chameleon_error("CHAMELEON_zunglq_param_Tile", "invalid third descriptor");
        return chameleon_request_fail(sequence, request, CHAMELEON_ERR_ILLEGAL_VALUE);
288
    }
Mathieu Faverge's avatar
Mathieu Faverge committed
289 290 291
    if (chameleon_desc_check(Q) != CHAMELEON_SUCCESS) {
        chameleon_error("CHAMELEON_zunglq_param_Tile", "invalid fourth descriptor");
        return chameleon_request_fail(sequence, request, CHAMELEON_ERR_ILLEGAL_VALUE);
292 293 294
    }
    /* Check input arguments */
    if (A->nb != A->mb || Q->nb != Q->mb) {
Mathieu Faverge's avatar
Mathieu Faverge committed
295 296
        chameleon_error("CHAMELEON_zunglq_param_Tile", "only square tiles supported");
        return chameleon_request_fail(sequence, request, CHAMELEON_ERR_ILLEGAL_VALUE);
297 298 299
    }
    /* Quick return - currently NOT equivalent to LAPACK's:
     * CALL DLASET( 'Full', MAX( M, N ), NRHS, ZERO, ZERO, Q, LDQ ) */
300 301
    /*
     if (chameleon_min(M, N) == 0)
302
     return CHAMELEON_SUCCESS;
303
     */
BOUCHERIE Raphael's avatar
BOUCHERIE Raphael committed
304
#if defined(CHAMELEON_COPY_DIAG)
Mathieu Faverge's avatar
Mathieu Faverge committed
305
    {
306
        int m = chameleon_min(A->m, A->n);
Mathieu Faverge's avatar
Mathieu Faverge committed
307
        chameleon_zdesc_alloc(D, A->mb, A->nb, m, A->n, 0, 0, m, A->n, );
Mathieu Faverge's avatar
Mathieu Faverge committed
308 309
        Dptr = &D;
    }
BOUCHERIE Raphael's avatar
BOUCHERIE Raphael committed
310
#endif
Mathieu Faverge's avatar
Mathieu Faverge committed
311

Mathieu Faverge's avatar
Mathieu Faverge committed
312
    chameleon_pzlaset( ChamUpperLower, 0., 1., Q, sequence, request );
313
    chameleon_pzunglq_param( 1, qrtree, A, Q, TS, TT, Dptr, sequence, request );
Mathieu Faverge's avatar
Mathieu Faverge committed
314 315

    if (Dptr != NULL) {
316 317 318 319 320
        CHAMELEON_Desc_Flush( A, sequence );
        CHAMELEON_Desc_Flush( Q, sequence );
        CHAMELEON_Desc_Flush( TS, sequence );
        CHAMELEON_Desc_Flush( TT, sequence );
        CHAMELEON_Desc_Flush( Dptr, sequence );
Mathieu Faverge's avatar
Mathieu Faverge committed
321
        chameleon_sequence_wait( chamctxt, sequence );
322
        chameleon_desc_destroy( Dptr );
Mathieu Faverge's avatar
Mathieu Faverge committed
323
    }
BOUCHERIE Raphael's avatar
BOUCHERIE Raphael committed
324
    (void)D;
325
    return CHAMELEON_SUCCESS;
326
}