MAGMA  1.2.0
MatrixAlgebraonGPUandMulticoreArchitectures
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
zgetrs_gpu.cpp
Go to the documentation of this file.
1 /*
2  -- MAGMA (version 1.2.0) --
3  Univ. of Tennessee, Knoxville
4  Univ. of California, Berkeley
5  Univ. of Colorado, Denver
6  May 2012
7 
8  @precisions normal z -> s d c
9 
10 */
11 #include "common_magma.h"
12 
13 // === Define what BLAS to use ============================================
14 #define PRECISION_z
15 #if (defined(PRECISION_s) || defined(PRECISION_d))
16  #define magma_ztrsm magmablas_ztrsm
17 #endif
18 // === End defining what BLAS to use =======================================
19 
20 extern "C" magma_int_t
22  cuDoubleComplex *dA, magma_int_t ldda,
23  magma_int_t *ipiv,
24  cuDoubleComplex *dB, magma_int_t lddb,
25  magma_int_t *info)
26 {
27 /* -- MAGMA (version 1.2.0) --
28  Univ. of Tennessee, Knoxville
29  Univ. of California, Berkeley
30  Univ. of Colorado, Denver
31  May 2012
32 
33  Purpose
34  =======
35 
36  Solves a system of linear equations
37  A * X = B or A' * X = B
38  with a general N-by-N matrix A using the LU factorization computed by ZGETRF_GPU.
39 
40  Arguments
41  =========
42 
43  TRANS (input) CHARACTER*1
44  Specifies the form of the system of equations:
45  = 'N': A * X = B (No transpose)
46  = 'T': A'* X = B (Transpose)
47  = 'C': A'* X = B (Conjugate transpose = Transpose)
48 
49  N (input) INTEGER
50  The order of the matrix A. N >= 0.
51 
52  NRHS (input) INTEGER
53  The number of right hand sides, i.e., the number of columns
54  of the matrix B. NRHS >= 0.
55 
56  A (input) COMPLEX_16 array on the GPU, dimension (LDA,N)
57  The factors L and U from the factorization A = P*L*U as computed
58  by ZGETRF_GPU.
59 
60  LDA (input) INTEGER
61  The leading dimension of the array A. LDA >= max(1,N).
62 
63  IPIV (input) INTEGER array, dimension (N)
64  The pivot indices from ZGETRF; for 1<=i<=N, row i of the
65  matrix was interchanged with row IPIV(i).
66 
67  B (input/output) COMPLEX_16 array on the GPU, dimension (LDB,NRHS)
68  On entry, the right hand side matrix B.
69  On exit, the solution matrix X.
70 
71  LDB (input) INTEGER
72  The leading dimension of the array B. LDB >= max(1,N).
73 
74  INFO (output) INTEGER
75  = 0: successful exit
76  < 0: if INFO = -i, the i-th argument had an illegal value
77 
78  HWORK (workspace) COMPLEX_16 array, dimension N*NRHS
79  ===================================================================== */
80 
81 
82  cuDoubleComplex c_one = MAGMA_Z_ONE;
83  cuDoubleComplex *work = NULL;
84  char trans_[2] = {trans, 0};
85  long int notran = lapackf77_lsame(trans_, "N");
86  magma_int_t i1, i2, inc;
87 
88  *info = 0;
89  if ( (! notran) &&
90  (! lapackf77_lsame(trans_, "T")) &&
91  (! lapackf77_lsame(trans_, "C")) ) {
92  *info = -1;
93  } else if (n < 0) {
94  *info = -2;
95  } else if (nrhs < 0) {
96  *info = -3;
97  } else if (ldda < max(1,n)) {
98  *info = -5;
99  } else if (lddb < max(1,n)) {
100  *info = -8;
101  }
102  if (*info != 0) {
103  magma_xerbla( __func__, -(*info) );
104  return *info;
105  }
106 
107  /* Quick return if possible */
108  if (n == 0 || nrhs == 0) {
109  return *info;
110  }
111 
112  work = (cuDoubleComplex*)malloc(n * nrhs * sizeof(cuDoubleComplex));
113  if ( !work ) {
114  *info = MAGMA_ERR_HOST_ALLOC;
115  return *info;
116  }
117 
118  i1 = 1;
119  i2 = n;
120  if (notran) {
121  inc = 1;
122 
123  /* Solve A * X = B. */
124  magma_zgetmatrix( n, nrhs, dB, lddb, work, n );
125  lapackf77_zlaswp(&nrhs, work, &n, &i1, &i2, ipiv, &inc);
126  magma_zsetmatrix( n, nrhs, work, n, dB, lddb );
127 
128  if ( nrhs == 1) {
129  magma_ztrsv(MagmaLower, MagmaNoTrans, MagmaUnit, n, dA, ldda, dB, 1 );
130  magma_ztrsv(MagmaUpper, MagmaNoTrans, MagmaNonUnit, n, dA, ldda, dB, 1 );
131  } else {
132  magma_ztrsm(MagmaLeft, MagmaLower, MagmaNoTrans, MagmaUnit, n, nrhs, c_one, dA, ldda, dB, lddb );
133  magma_ztrsm(MagmaLeft, MagmaUpper, MagmaNoTrans, MagmaNonUnit, n, nrhs, c_one, dA, ldda, dB, lddb );
134  }
135  } else {
136  inc = -1;
137 
138  /* Solve A' * X = B. */
139  if ( nrhs == 1) {
140  magma_ztrsv(MagmaUpper, trans, MagmaNonUnit, n, dA, ldda, dB, 1 );
141  magma_ztrsv(MagmaLower, trans, MagmaUnit, n, dA, ldda, dB, 1 );
142  } else {
143  magma_ztrsm(MagmaLeft, MagmaUpper, trans, MagmaNonUnit, n, nrhs, c_one, dA, ldda, dB, lddb );
144  magma_ztrsm(MagmaLeft, MagmaLower, trans, MagmaUnit, n, nrhs, c_one, dA, ldda, dB, lddb );
145  }
146 
147  magma_zgetmatrix( n, nrhs, dB, lddb, work, n );
148  lapackf77_zlaswp(&nrhs, work, &n, &i1, &i2, ipiv, &inc);
149  magma_zsetmatrix( n, nrhs, work, n, dB, lddb );
150  }
151  free(work);
152 
153  return *info;
154 }
155