PLASMA  2.4.5
PLASMA - Parallel Linear Algebra for Scalable Multi-core Architectures
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
testing_zcungesv.c
Go to the documentation of this file.
1 
15 #include <stdlib.h>
16 #include <stdio.h>
17 #include <string.h>
18 #include <math.h>
19 
20 #include <plasma.h>
21 #include <cblas.h>
22 #include <lapacke.h>
23 #include <core_blas.h>
24 #include "testing_zmain.h"
25 
26 static int check_solution(int, int, PLASMA_Complex64_t*, int, PLASMA_Complex64_t*, PLASMA_Complex64_t*, int, double);
27 
28 int testing_zcungesv(int argc, char **argv)
29 {
30  /* Check for number of arguments*/
31  if (argc != 4){
32  USAGE("CUNGESV", "N LDA NRHS LDB",
33  " - N : the size of the matrix\n"
34  " - LDA : leading dimension of the matrix A\n"
35  " - NRHS : number of RHS\n"
36  " - LDB : leading dimension of the RHS B\n");
37  return -1;
38  }
39 
40  int N = atoi(argv[0]);
41  int LDA = atoi(argv[1]);
42  int NRHS = atoi(argv[2]);
43  int LDB = atoi(argv[3]);
44  int ITER;
45 
46  double eps;
47  int info, info_solution;
48  int i,j;
49  int LDAxN = LDA*N;
50  int LDBxNRHS = LDB*NRHS;
51 
52  PLASMA_Complex64_t *A1 = (PLASMA_Complex64_t *)malloc(LDA*N *sizeof(PLASMA_Complex64_t));
53  PLASMA_Complex64_t *A2 = (PLASMA_Complex64_t *)malloc(LDA*N *sizeof(PLASMA_Complex64_t));
54  PLASMA_Complex64_t *B1 = (PLASMA_Complex64_t *)malloc(LDB*NRHS*sizeof(PLASMA_Complex64_t));
55  PLASMA_Complex64_t *B2 = (PLASMA_Complex64_t *)malloc(LDB*NRHS*sizeof(PLASMA_Complex64_t));
56 
57  /* Check if unable to allocate memory */
58  if ( (!A1) || (!A2) || (!B1) || (!B2) ) {
59  printf("Out of Memory \n ");
60  exit(0);
61  }
62 
63  eps = LAPACKE_dlamch_work('e');
64 
65  /*----------------------------------------------------------
66  * TESTING ZCGELS
67  */
68 
69  /* Initialize A1 and A2 */
70  LAPACKE_zlarnv_work(IONE, ISEED, LDAxN, A1);
71  for (i = 0; i < N; i++)
72  for (j = 0; j < N; j++)
73  A2[LDA*j+i] = A1[LDA*j+i] ;
74 
75  /* Initialize B1 and B2 */
76  LAPACKE_zlarnv_work(IONE, ISEED, LDBxNRHS, B1);
77  for (i = 0; i < N; i++)
78  for (j = 0; j < NRHS; j++)
79  B2[LDB*j+i] = B1[LDB*j+i] ;
80 
81  printf("\n");
82  printf("------ TESTS FOR PLASMA ZCUNGESV ROUTINE ------- \n");
83  printf(" Size of the Matrix %d by %d\n", N, N);
84  printf("\n");
85  printf(" The matrix A is randomly generated for each test.\n");
86  printf("============\n");
87  printf(" The relative machine precision (eps) is to be %e \n",eps);
88  printf(" Computational tests pass if scaled residuals are less than 60.\n");
89 
90  /* PLASMA ZCUNGESV */
91  info = PLASMA_zcungesv(PlasmaNoTrans, N, NRHS, A2, LDA, B1, LDB, B2, LDB, &ITER);
92  if (info != PLASMA_SUCCESS ) {
93  printf("PLASMA_zcposv is not completed: info = %d\n", info);
94  info_solution = 1;
95  } else {
96  printf(" Solution obtained with %d iterations\n", ITER);
97 
98  /* Check the orthogonality, factorization and the solution */
99  info_solution = check_solution(N, NRHS, A1, LDA, B1, B2, LDB, eps);
100  }
101 
102  if (info_solution == 0) {
103  printf("***************************************************\n");
104  printf(" ---- TESTING ZCUNGESV.................... PASSED !\n");
105  printf("***************************************************\n");
106  }
107  else {
108  printf("************************************************\n");
109  printf(" - TESTING ZCUNGESV .. FAILED !\n");
110  printf("************************************************\n");
111  }
112 
113  free(A1); free(A2); free(B1); free(B2);
114 
115  return 0;
116 }
117 
118 /*--------------------------------------------------------------
119  * Check the solution
120  */
121 
122 static int check_solution(int N, int NRHS, PLASMA_Complex64_t *A1, int LDA, PLASMA_Complex64_t *B1, PLASMA_Complex64_t *B2, int LDB, double eps )
123 {
124  int info_solution;
125  double Rnorm, Anorm, Xnorm, Bnorm, result;
126  PLASMA_Complex64_t alpha, beta;
127  double *work = (double *)malloc(N*sizeof(double));
128 
129  alpha = 1.0;
130  beta = -1.0;
131 
132  Anorm = LAPACKE_zlange_work(LAPACK_COL_MAJOR, lapack_const(PlasmaInfNorm), N, N, A1, LDA, work);
133  Xnorm = LAPACKE_zlange_work(LAPACK_COL_MAJOR, lapack_const(PlasmaInfNorm), N, NRHS, B2, LDB, work);
134  Bnorm = LAPACKE_zlange_work(LAPACK_COL_MAJOR, lapack_const(PlasmaInfNorm), N, NRHS, B1, LDB, work);
135 
136  cblas_zgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, N, NRHS, N, CBLAS_SADDR(alpha), A1, LDA, B2, LDB, CBLAS_SADDR(beta), B1, LDB);
137  Rnorm = LAPACKE_zlange_work(LAPACK_COL_MAJOR, lapack_const(PlasmaInfNorm), N, NRHS, B1, LDB, work);
138 
139  if (getenv("PLASMA_TESTING_VERBOSE"))
140  printf( "||A||_oo=%f\n||X||_oo=%f\n||B||_oo=%f\n||A X - B||_oo=%e\n", Anorm, Xnorm, Bnorm, Rnorm );
141 
142  result = Rnorm / ( (Anorm*Xnorm+Bnorm)*N*eps ) ;
143  printf("============\n");
144  printf("Checking the Residual of the solution \n");
145  printf("-- ||Ax-B||_oo/((||A||_oo||x||_oo+||B||_oo).N.eps) = %e \n", result);
146 
147  if ( isnan(Xnorm) || isinf(Xnorm) || isnan(result) || isinf(result) || (result > 60.0) ) {
148  printf("-- The solution is suspicious ! \n");
149  info_solution = 1;
150  }
151  else{
152  printf("-- The solution is CORRECT ! \n");
153  info_solution = 0;
154  }
155 
156  free(work);
157 
158  return info_solution;
159 }