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_ssyrk.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_smain.h"
25 
26 static int check_solution(PLASMA_enum uplo, PLASMA_enum trans, int N, int K,
27  float alpha, float *A, int LDA,
28  float beta, float *Cref, float *Cplasma, int LDC);
29 
30 
31 int testing_ssyrk(int argc, char **argv)
32 {
33  /* Check for number of arguments*/
34  if ( argc != 6){
35  USAGE("SYRK", "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  float *A = (float *)malloc(LDAxK*sizeof(float));
60  float *C = (float *)malloc(LDCxN*sizeof(float));
61  float *Cinit = (float *)malloc(LDCxN*sizeof(float));
62  float *Cfinal = (float *)malloc(LDCxN*sizeof(float));
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 SSYRK 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 SSYRK
83  */
84 
85  /* Initialize A */
86  LAPACKE_slarnv_work(IONE, ISEED, LDAxK, A);
87 
88  /* Initialize C */
89  PLASMA_splgsy( (float)0., N, C, LDC, 51 );
90 
91  for (u=0; u<2; u++) {
92  for (t=0; t<2; t++) {
93  memcpy(Cinit, C, LDCxN*sizeof(float));
94  memcpy(Cfinal, C, LDCxN*sizeof(float));
95 
96  /* PLASMA SSYRK */
97  PLASMA_ssyrk(uplo[u], trans[t], N, K, alpha, A, LDA, beta, Cfinal, LDC);
98 
99  /* Check the solution */
100  info_solution = check_solution(uplo[u], trans[t], N, K,
101  alpha, A, LDA, beta, Cinit, Cfinal, LDC);
102 
103  if (info_solution == 0) {
104  printf("***************************************************\n");
105  printf(" ---- TESTING SSYRK (%5s, %s) ........... PASSED !\n", uplostr[u], transstr[t]);
106  printf("***************************************************\n");
107  }
108  else {
109  printf("************************************************\n");
110  printf(" - TESTING SSYRK (%5s, %s) ... FAILED !\n", uplostr[u], transstr[t]);
111  printf("************************************************\n");
112  }
113  }
114  }
115 
116  free(A); free(C);
117  free(Cinit); free(Cfinal);
118 
119  return 0;
120 }
121 
122 /*--------------------------------------------------------------
123  * Check the solution
124  */
125 
126 static int check_solution(PLASMA_enum uplo, PLASMA_enum trans, int N, int K,
127  float alpha, float *A, int LDA,
128  float beta, float *Cref, float *Cplasma, int LDC)
129 {
130  int info_solution;
131  float Anorm, Cinitnorm, Cplasmanorm, Clapacknorm, Rnorm;
132  float eps;
133  float beta_const;
134  float result;
135  float *work = (float *)malloc(max(N, K)* sizeof(float));
136 
137  beta_const = -1.0;
138  Anorm = LAPACKE_slange_work(LAPACK_COL_MAJOR, lapack_const(PlasmaInfNorm),
139  (trans == PlasmaNoTrans) ? N : K,
140  (trans == PlasmaNoTrans) ? K : N, A, LDA, work);
141  Cinitnorm = LAPACKE_slange_work(LAPACK_COL_MAJOR, lapack_const(PlasmaInfNorm), N, N, Cref, LDC, work);
142  Cplasmanorm = LAPACKE_slange_work(LAPACK_COL_MAJOR, lapack_const(PlasmaInfNorm), N, N, Cplasma, LDC, work);
143 
145  N, K, (alpha), A, LDA, (beta), Cref, LDC);
146 
147  Clapacknorm = LAPACKE_slange_work(LAPACK_COL_MAJOR, lapack_const(PlasmaInfNorm), N, N, Cref, LDC, work);
148 
149  cblas_saxpy(LDC*N, (beta_const), Cplasma, 1, Cref, 1);
150 
151  Rnorm = LAPACKE_slange_work(LAPACK_COL_MAJOR, lapack_const(PlasmaInfNorm), N, N, Cref, LDC, work);
152 
153  eps = LAPACKE_slamch_work('e');
154 
155  printf("Rnorm %e, Anorm %e, Cinitnorm %e, Cplasmanorm %e, Clapacknorm %e\n",
156  Rnorm, Anorm, Cinitnorm, Cplasmanorm, Clapacknorm);
157 
158  result = Rnorm / ((Anorm + Cinitnorm) * N * eps);
159 
160  printf("============\n");
161  printf("Checking the norm of the difference against reference SSYRK \n");
162  printf("-- ||Cplasma - Clapack||_oo/((||A||_oo+||C||_oo).N.eps) = %e \n", result);
163 
164  if ( isinf(Clapacknorm) || isinf(Cplasmanorm) || isnan(result) || isinf(result) || (result > 10.0) ) {
165  printf("-- The solution is suspicious ! \n");
166  info_solution = 1;
167  }
168  else {
169  printf("-- The solution is CORRECT ! \n");
170  info_solution= 0 ;
171  }
172 
173  free(work);
174 
175  return info_solution;
176 }