01: /* ///////////////////////////// P /// L /// A /// S /// M /// A /////////////////////////////// */
02: /* ///                    PLASMA auxiliary routines (version 2.1.0)                          ///
03:  * ///                    Release Date: November, 15th 2009                                  ///
04:  * ///                    PLASMA is a software package provided by Univ. of Tennessee,       ///
05:  * ///                    Univ. of California Berkeley and Univ. of Colorado Denver          /// */
06: /* ///////////////////////////////////////////////////////////////////////////////////////////// */
07: #include "common.h"
08: #include "lapack.h"
09: 
10: /* ///////////////////////////////////////////////////////////////////////////////////////////// */
11: #define A(m,n) &((double*)A.mat)[A.bsiz*(m)+A.bsiz*A.lmt*(n)]
12: 
13: /* Approximation of the norm to fit tile storage. 
14:    Returns the max of the norms of the tiles. */
15: void plasma_pdlange(plasma_context_t *plasma)
16: {
17:     char norm;
18:     PLASMA_desc A;
19:     double global_norm;
20:     double local_norm;
21:     double *returned_norm;
22: 
23:     double* rwork;
24: 
25:     int X, X1, X2, Y, Y1, Y2;
26:     int m, n;
27:     int next_m;
28:     int next_n;
29: 
30:     plasma_unpack_args_3(norm, A, returned_norm);
31: 
32:     rwork = (double *)plasma_private_alloc(plasma, A.nb, PlasmaRealDouble);
33: 
34: 
35:     global_norm = 0.0;
36: 
37:     n = 0;
38:     m = PLASMA_RANK;
39:     while (m >= A.mt && n < A.nt) {
40:         n++;
41:         m = m-A.mt;
42:     }
43: 
44:     while (n < A.nt) {
45:         next_m = m;
46:         next_n = n;
47: 
48:         next_m += PLASMA_SIZE;
49:         while (next_m >= A.mt && next_n < A.nt) {
50:             next_n++;
51:             next_m = next_m-A.mt;
52:         }
53: 
54:         X1 = m == 0 ? A.i%A.nb : 0;
55:         Y1 = n == 0 ? A.j%A.nb : 0;
56:         X2 = m == A.mt-1 ? (A.i+A.m-1)%A.nb+1 : A.nb;
57:         Y2 = n == A.nt-1 ? (A.j+A.n-1)%A.nb+1 : A.nb;
58:         X = X2 - X1;
59:         Y = Y2 - Y1;
60: 
61:         local_norm = dlange( &norm, &X, &Y, A(m,n), &A.nb, rwork);
62:         if (local_norm > global_norm) global_norm = local_norm;
63: 
64:         m = next_m;
65:         n = next_n;
66:     }
67: 
68:     returned_norm[PLASMA_RANK] = global_norm;
69:     plasma_private_free(plasma, rwork);
70: }
71: 
72: