legacy_real_1stage_c_version.c 7.24 KB
Newer Older
Andreas Marek's avatar
Andreas Marek committed
1
2
3
4
5
/*     This file is part of ELPA. */
/*  */
/*     The ELPA library was originally created by the ELPA consortium, */
/*     consisting of the following organizations: */
/*  */
6
7
/*     - Max Planck Computing and Data Facility (MPCDF), formerly known as */
/*       Rechenzentrum Garching der Max-Planck-Gesellschaft (RZG), */
Andreas Marek's avatar
Andreas Marek committed
8
9
10
11
12
13
14
15
16
17
18
19
/*     - Bergische Universität Wuppertal, Lehrstuhl für angewandte */
/*       Informatik, */
/*     - Technische Universität München, Lehrstuhl für Informatik mit */
/*       Schwerpunkt Wissenschaftliches Rechnen , */
/*     - Fritz-Haber-Institut, Berlin, Abt. Theorie, */
/*     - Max-Plack-Institut für Mathematik in den Naturwissenschaften, */
/*       Leipzig, Abt. Komplexe Strukutren in Biologie und Kognition, */
/*       and */
/*     - IBM Deutschland GmbH */
/*  */
/*  */
/*     More information can be found here: */
20
/*     http://elpa.mpcdf.mpg.de/ */
Andreas Marek's avatar
Andreas Marek committed
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/*  */
/*     ELPA is free software: you can redistribute it and/or modify */
/*     it under the terms of the version 3 of the license of the */
/*     GNU Lesser General Public License as published by the Free */
/*     Software Foundation. */
/*  */
/*     ELPA is distributed in the hope that it will be useful, */
/*     but WITHOUT ANY WARRANTY; without even the implied warranty of */
/*     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the */
/*     GNU Lesser General Public License for more details. */
/*  */
/*     You should have received a copy of the GNU Lesser General Public License */
/*     along with ELPA.  If not, see <http://www.gnu.org/licenses/> */
/*  */
/*     ELPA reflects a substantial effort on the part of the original */
/*     ELPA consortium, and we ask you to respect the spirit of the */
/*     license that we chose: i.e., please contribute any changes you */
/*     may have back to the original ELPA library distribution, and keep */
/*     any derivatives of ELPA under the same license that we chose for */
/*     the original distribution, the GNU Lesser General Public License. */
/*  */
/*  */

#include "config-f90.h"

#include <stdio.h>
#include <stdlib.h>
48
#ifdef WITH_MPI
Andreas Marek's avatar
Andreas Marek committed
49
#include <mpi.h>
50
#endif
Andreas Marek's avatar
Andreas Marek committed
51
52
#include <math.h>

53
#include <elpa/elpa_legacy.h>
Andreas Marek's avatar
Andreas Marek committed
54

55
#include "test/shared/generated.h"
56

57
58
#define DOUBLE_PRECISION_REAL 1

59
int main(int argc, char** argv) {
60
61
   int myid;
   int nprocs;
62
63
64
#ifndef WITH_MPI
   int MPI_COMM_WORLD;
#endif
65
   int na, nev, nblk;
Andreas Marek's avatar
Andreas Marek committed
66

67
   int status;
Andreas Marek's avatar
Andreas Marek committed
68

69
   int np_cols, np_rows, np_colsStart;
Andreas Marek's avatar
Andreas Marek committed
70

71
   int my_blacs_ctxt, nprow, npcol, my_prow, my_pcol;
Andreas Marek's avatar
Andreas Marek committed
72

73
   int mpierr;
Andreas Marek's avatar
Andreas Marek committed
74

75
76
   int my_mpi_comm_world;
   int mpi_comm_rows, mpi_comm_cols;
Andreas Marek's avatar
Andreas Marek committed
77

78
   int info, *sc_desc;
Andreas Marek's avatar
Andreas Marek committed
79

80
81
   int na_rows, na_cols;
   double startVal;
82
#ifdef DOUBLE_PRECISION_REAL
83
   double *a, *z, *as, *ev;
84
#else
85
   float *a, *z, *as, *ev;
86
#endif
Andreas Marek's avatar
Andreas Marek committed
87

88
   int success;
89
90

   int useGPU;
91
#ifdef WITH_MPI
92
93
94
   MPI_Init(&argc, &argv);
   MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
   MPI_Comm_rank(MPI_COMM_WORLD, &myid);
95
96
97
98
99
#else
   nprocs = 1;
   myid = 0;
   MPI_COMM_WORLD=1;
#endif
100
101
102
   na = 1000;
   nev = 500;
   nblk = 16;
Andreas Marek's avatar
Andreas Marek committed
103

104
105
106
107
108
109
110
111
   if (myid == 0) {
     printf("This is the c version of an ELPA test-programm\n");
     printf("\n");
     printf("It will call the 1stage ELPA real solver for an\n");
     printf("of matrix size %d. It will compute %d eigenvalues\n",na,nev);
     printf("and uses a blocksize of %d\n",nblk);
     printf("\n");
     printf("This is an example program with much less functionality\n");
Andreas Marek's avatar
Andreas Marek committed
112
113
     printf("as it's Fortran counterpart. It's only purpose is to show how \n");
     printf("to evoke ELPA1 from a c programm\n");
114
     printf("\n");
115
116
117
118
119
120
#ifdef DOUBLE_PRECISION_REAL
     printf("The double precision version of ELPA1 is used\n");
#else
     printf("The single precision version of ELPA1 is used\n");
#endif
     printf("\n");
Andreas Marek's avatar
Andreas Marek committed
121

122
   }
Andreas Marek's avatar
Andreas Marek committed
123

124
   status = 0;
Andreas Marek's avatar
Andreas Marek committed
125

126
127
128
129
130
131
132
   startVal = sqrt((double) nprocs);
   np_colsStart = (int) round(startVal);
   for (np_cols=np_colsStart;np_cols>1;np_cols--){
     if (nprocs %np_cols ==0){
     break;
     }
   }
Andreas Marek's avatar
Andreas Marek committed
133

134
   np_rows = nprocs/np_cols;
Andreas Marek's avatar
Andreas Marek committed
135

136
137
138
139
   if (myid == 0) {
     printf("\n");
     printf("Number of processor rows %d, cols %d, total %d \n",np_rows,np_cols,nprocs);
   }
Andreas Marek's avatar
Andreas Marek committed
140

141
142
   /* set up blacs */
   /* convert communicators before */
143
#ifdef WITH_MPI
Andreas Marek's avatar
Andreas Marek committed
144
   my_mpi_comm_world = MPI_Comm_c2f(MPI_COMM_WORLD);
145
#endif
146
   set_up_blacsgrid_f(my_mpi_comm_world, &my_blacs_ctxt, &np_rows, &np_cols, &nprow, &npcol, &my_prow, &my_pcol);
Andreas Marek's avatar
Andreas Marek committed
147
148
149
150
151
152
153

   if (myid == 0) {
     printf("\n");
     printf("Past BLACS_Gridinfo...\n");
     printf("\n");
   }

154
155
   /* get the ELPA row and col communicators. */
   /* These are NOT usable in C without calling the MPI_Comm_f2c function on them !! */
156
#ifdef WITH_MPI
Andreas Marek's avatar
Andreas Marek committed
157
   my_mpi_comm_world = MPI_Comm_c2f(MPI_COMM_WORLD);
158
159
160
#else
   my_mpi_comm_world =1 ;
#endif
161
   mpierr = elpa_get_communicators(my_mpi_comm_world, my_prow, my_pcol, &mpi_comm_rows, &mpi_comm_cols);
Andreas Marek's avatar
Andreas Marek committed
162
163
164
165
166
167
168
169
170

   if (myid == 0) {
     printf("\n");
     printf("Past split communicator setup for rows and columns...\n");
     printf("\n");
   }

   sc_desc = malloc(9*sizeof(int));

171
   set_up_blacs_descriptor_f(na, nblk, my_prow, my_pcol, np_rows, np_cols, &na_rows, &na_cols, sc_desc, my_blacs_ctxt, &info);
Andreas Marek's avatar
Andreas Marek committed
172
173
174
175
176
177
178

   if (myid == 0) {
     printf("\n");
     printf("Past scalapack descriptor setup...\n");
     printf("\n");
   }

179
   /* allocate the matrices needed for elpa */
Andreas Marek's avatar
Andreas Marek committed
180
181
182
183
184
   if (myid == 0) {
     printf("\n");
     printf("Allocating matrices with na_rows=%d and na_cols=%d\n",na_rows, na_cols);
     printf("\n");
   }
185
#ifdef DOUBLE_PRECISION_REAL
Andreas Marek's avatar
Andreas Marek committed
186
187
188
189
   a  = malloc(na_rows*na_cols*sizeof(double));
   z  = malloc(na_rows*na_cols*sizeof(double));
   as = malloc(na_rows*na_cols*sizeof(double));
   ev = malloc(na*sizeof(double));
190
191
192
193
194
195
196
197
#else
   a  = malloc(na_rows*na_cols*sizeof(float));
   z  = malloc(na_rows*na_cols*sizeof(float));
   as = malloc(na_rows*na_cols*sizeof(float));
   ev = malloc(na*sizeof(float));
#endif

#ifdef DOUBLE_PRECISION_REAL
198
   prepare_matrix_real_double_f(na, myid, na_rows, na_cols, sc_desc, a, z, as);
199
#else
200
   prepare_matrix_real_single_f(na, myid, na_rows, na_cols, sc_desc, a, z, as);
201
#endif
Andreas Marek's avatar
Andreas Marek committed
202
203
204
205
206
   if (myid == 0) {
     printf("\n");
     printf("Entering ELPA 1stage real solver\n");
     printf("\n");
   }
207
#ifdef WITH_MPI
Andreas Marek's avatar
Andreas Marek committed
208
   mpierr = MPI_Barrier(MPI_COMM_WORLD);
209
#endif
210

211
#ifdef DOUBLE_PRECISION_REAL
212
213
   useGPU = 0;
   success = elpa_solve_evp_real_1stage_double_precision(na, nev, a, na_rows, ev, z, na_rows, nblk, na_cols, mpi_comm_rows, mpi_comm_cols, my_mpi_comm_world, useGPU);
214
#else
215
   success = elpa_solve_evp_real_1stage_single_precision(na, nev, a, na_rows, ev, z, na_rows, nblk, na_cols, mpi_comm_rows, mpi_comm_cols, my_mpi_comm_world, useGPU);
216
#endif
Andreas Marek's avatar
Andreas Marek committed
217
218
219

   if (success != 1) {
     printf("error in ELPA solve \n");
220
#ifdef WITH_MPI
Andreas Marek's avatar
Andreas Marek committed
221
     mpierr = MPI_Abort(MPI_COMM_WORLD, 99);
222
223
#else
     exit(99);
224
#endif
Andreas Marek's avatar
Andreas Marek committed
225
226
227
228
229
230
231
232
233
   }


   if (myid == 0) {
     printf("\n");
     printf("1stage ELPA real solver complete\n");
     printf("\n");
   }

234
#ifdef DOUBLE_PRECISION_REAL
235
   /* check the results */
236
   status = check_correctness_real_double_f(na, nev, na_rows, na_cols, as, z, ev, sc_desc, myid);
237
#else
238
   status = check_correctness_real_single_f(na, nev, na_rows, na_cols, as, z, ev, sc_desc, myid);
239
#endif
Andreas Marek's avatar
Andreas Marek committed
240
241
242
243
244
245
246
   if (status !=0){
     printf("The computed EVs are not correct !\n");
   }
   if (status ==0){
     printf("All ok!\n");
   }

247
248
249
250
   free(sc_desc);
   free(a);
   free(z);
   free(as);
251
   free(ev);
252

253
#ifdef WITH_MPI
254
   MPI_Finalize();
255
#endif
256
   return 0;
Andreas Marek's avatar
Andreas Marek committed
257
}