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_cherk.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_cmain.h"
25 
26 static int check_solution(PLASMA_enum uplo, PLASMA_enum trans, int N, int K,
27  float alpha, PLASMA_Complex32_t *A, int LDA,
28  float beta, PLASMA_Complex32_t *Cref, PLASMA_Complex32_t *Cplasma, int LDC);
29 
30 
31 int testing_cherk(int argc, char **argv)
32 {
33  /* Check for number of arguments*/
34  if ( argc != 6 ){
35  USAGE("HERK", "alpha beta M N LDA LDC",
36  " - alpha : alpha coefficient\n"
37  " - beta : beta coefficient\n"
38  " - N : number of columns and rows of matrix C and number of row of matrix A\n"
39  " - K : number of columns of matrix A\n"
40  " - LDA : leading dimension of matrix A\n"
41  " - LDC : leading dimension of matrix C\n");
42  return -1;
43  }
44 
45  float alpha = (float) atol(argv[0]);
46  float beta = (float) atol(argv[1]);
47  int N = atoi(argv[2]);
48  int K = atoi(argv[3]);
49  int LDA = atoi(argv[4]);
50  int LDC = atoi(argv[5]);
51  int NKmax = max(N, K);
52 
53  float eps;
54  int info_solution;
55  int u, t;
56  size_t LDAxK = LDA*NKmax;
57  size_t LDCxN = LDC*N;
58 
59  PLASMA_Complex32_t *A = (PLASMA_Complex32_t *)malloc(LDAxK*sizeof(PLASMA_Complex32_t));
60  PLASMA_Complex32_t *C = (PLASMA_Complex32_t *)malloc(LDCxN*sizeof(PLASMA_Complex32_t));
61  PLASMA_Complex32_t *Cinit = (PLASMA_Complex32_t *)malloc(LDCxN*sizeof(PLASMA_Complex32_t));
62  PLASMA_Complex32_t *Cfinal = (PLASMA_Complex32_t *)malloc(LDCxN*sizeof(PLASMA_Complex32_t));
63 
64  /* Check if unable to allocate memory */
65  if ( (!A) || (!Cinit) || (!Cfinal) ){
66  printf("Out of Memory \n ");
67  return -2;
68  }
69 
70  eps = LAPACKE_slamch_work('e');
71 
72  printf("\n");
73  printf("------ TESTS FOR PLASMA CHERK ROUTINE ------- \n");
74  printf(" Size of the Matrix A %d by %d\n", N, K);
75  printf("\n");
76  printf(" The matrix A is randomly generated for each test.\n");
77  printf("============\n");
78  printf(" The relative machine precision (eps) is to be %e \n",eps);
79  printf(" Computational tests pass if scaled residuals are less than 10.\n");
80 
81  /*----------------------------------------------------------
82  * TESTING CHERK
83  */
84 
85  /* Initialize A */
86  LAPACKE_clarnv_work(IONE, ISEED, LDAxK, A);
87 
88  /* Initialize C */
89  PLASMA_cplgsy( (float)0., N, C, LDC, 51 );
90 
91  for (u=0; u<2; u++) {
92  for (t=0; t<3; t++) {
93  if (trans[t] == PlasmaTrans) continue;
94 
95  memcpy(Cinit, C, LDCxN*sizeof(PLASMA_Complex32_t));
96  memcpy(Cfinal, C, LDCxN*sizeof(PLASMA_Complex32_t));
97 
98  /* PLASMA CHERK */
99  PLASMA_cherk(uplo[u], trans[t], N, K, alpha, A, LDA, beta, Cfinal, LDC);
100 
101  /* Check the solution */
102  info_solution = check_solution(uplo[u], trans[t], N, K,
103  alpha, A, LDA, beta, Cinit, Cfinal, LDC);
104 
105  if (info_solution == 0) {
106  printf("***************************************************\n");
107  printf(" ---- TESTING CHERK (%5s, %s) ........... PASSED !\n", uplostr[u], transstr[t]);
108  printf("***************************************************\n");
109  }
110  else {
111  printf("************************************************\n");
112  printf(" - TESTING CHERK (%5s, %s) ... FAILED !\n", uplostr[u], transstr[t]);
113  printf("************************************************\n");
114  }
115  }
116  }
117 
118  free(A); free(C);
119  free(Cinit); free(Cfinal);
120 
121  return 0;
122 }
123 
124 /*--------------------------------------------------------------
125  * Check the solution
126  */
127 
128 static int check_solution(PLASMA_enum uplo, PLASMA_enum trans, int N, int K,
129  float alpha, PLASMA_Complex32_t *A, int LDA,
130  float beta, PLASMA_Complex32_t *Cref, PLASMA_Complex32_t *Cplasma, int LDC)
131 {
132  int info_solution;
133  float Anorm, Cinitnorm, Cplasmanorm, Clapacknorm, Rnorm;
134  float eps;
135  PLASMA_Complex32_t beta_const;
136  float result;
137  float *work = (float *)malloc(max(N, K)* sizeof(float));
138 
139  beta_const = -1.0;
140  Anorm = LAPACKE_clange_work(LAPACK_COL_MAJOR, lapack_const(PlasmaInfNorm),
141  (trans == PlasmaNoTrans) ? N : K,
142  (trans == PlasmaNoTrans) ? K : N, A, LDA, work);
143  Cinitnorm = LAPACKE_clange_work(LAPACK_COL_MAJOR, lapack_const(PlasmaInfNorm), N, N, Cref, LDC, work);
144  Cplasmanorm = LAPACKE_clange_work(LAPACK_COL_MAJOR, lapack_const(PlasmaInfNorm), N, N, Cplasma, LDC, work);
145 
147  N, K, (alpha), A, LDA, (beta), Cref, LDC);
148 
149  Clapacknorm = LAPACKE_clange_work(LAPACK_COL_MAJOR, lapack_const(PlasmaInfNorm), N, N, Cref, LDC, work);
150 
151  cblas_caxpy(LDC*N, CBLAS_SADDR(beta_const), Cplasma, 1, Cref, 1);
152 
153  Rnorm = LAPACKE_clange_work(LAPACK_COL_MAJOR, lapack_const(PlasmaInfNorm), N, N, Cref, LDC, work);
154 
155  eps = LAPACKE_slamch_work('e');
156 
157  printf("Rnorm %e, Anorm %e, Cinitnorm %e, Cplasmanorm %e, Clapacknorm %e\n",
158  Rnorm, Anorm, Cinitnorm, Cplasmanorm, Clapacknorm);
159 
160  result = Rnorm / ((Anorm + Cinitnorm) * N * eps);
161 
162  printf("============\n");
163  printf("Checking the norm of the difference against reference CHERK \n");
164  printf("-- ||Cplasma - Clapack||_oo/((||A||_oo+||C||_oo).N.eps) = %e \n", result);
165 
166  if ( isinf(Clapacknorm) || isinf(Cplasmanorm) || isnan(result) || isinf(result) || (result > 10.0) ) {
167  printf("-- The solution is suspicious ! \n");
168  info_solution = 1;
169  }
170  else {
171  printf("-- The solution is CORRECT ! \n");
172  info_solution= 0 ;
173  }
174 
175  free(work);
176 
177  return info_solution;
178 }