source: pcp/src/helpers.c@ 64ca279

Last change on this file since 64ca279 was a0bcf1, checked in by Frederik Heber <heber@…>, 17 years ago

-initial commit
-Minimum set of files needed from ESPACK SVN repository
-Switch to three tantamount package parts instead of all relating to pcp (as at some time Ralf's might find inclusion as well)

  • Property mode set to 100644
File size: 20.4 KB
Line 
1/** \file helpers.c
2 * Malloc-, Realloc-, Free-wrappers and other small routines.
3 *
4 * This file contains small helpful routines that do such omnipresent tasks
5 * as allocation memory Malloc(), Malloci(), Mallocii(), reallocating Realloc(),
6 * Realloci(), Reallocii() or disallocating Free() with checks error messages
7 * in the case of failure. Speed Measuring is initiated InitSpeedMeasure() by setting
8 * SpeedStruct entries to zero,
9 * completed for output to file CompleteSpeedMeasure() and actually performed
10 * SpeedMeasure() herein.\n
11 * RemoveEverything() frees all memory that was alloceted during the course of the
12 * programme.\n
13 * StartParallel() initializes process groups and ranks, while WaitForOtherProcs()
14 * waits for the other running processes between the end of init phase and the begin
15 * of the calculation.\n
16 * Finally, GetRGB() does a colour translation of an RGB value from integer but it's
17 * not used anymore.
18 *
19 Project: ParallelCarParrinello
20 \author Jan Hamaekers
21 \date 2000
22
23 File: helpers.c
24 $Id: helpers.c,v 1.39 2007-02-12 09:44:55 foo Exp $
25*/
26
27#include <stdlib.h>
28#include <stdio.h>
29#include <stddef.h>
30#include <math.h>
31#include <string.h>
32#include "data.h"
33#include "errors.h"
34#include "helpers.h"
35#include "grad.h"
36#include "pseudo.h"
37#include "ions.h"
38#include "output.h"
39#include "run.h"
40#include "gramsch.h"
41#include "mymath.h"
42#include "myfft.h"
43#include "perturbed.h"
44
45/** Output of a debug message to stderr.
46 * \param *P Problem at hand, points to ParallelSimulationData#me
47 * \param output output string
48 */
49void debug(struct Problem *P, const char *output) {
50 if (output) fprintf(stderr,"(%i) %s\n",P->Par.me, output);
51}
52
53/** Malloc with error check.
54 * malloc() wrapper, printing error on null pointer
55 * \param size size of memory to be allocated
56 * \param output error message to be given on failure
57 */
58void* Malloc(size_t size, const char* output)
59{
60 void* dummy = malloc(size);
61 if (!dummy)
62 Error(MallocError, output);
63 return dummy;
64}
65
66/** Malloc string array and set its length to the allocated length.
67 * \param *output message if malloc fails
68 * \param size number of chars to alloc for \a *buffer
69 * \return pointer to string array
70 */
71char* MallocString(size_t size, const char* output) {
72 int i;
73 char *buffer;
74 buffer = Malloc(sizeof(char) * (size+1), output); // alloc
75 for (i=0;i<size;i++) // reset
76 buffer[i] = i % 2 == 0 ? 'p': 'c';
77 buffer[size] = '\0'; // and set length marker on its end
78 return(buffer);
79}
80
81
82/** Malloc with error check and 1 int.
83 * malloc() wrapper, printing error on null pointer
84 * \param size size of memory to be allocated
85 * \param output error message to be given on failure (containing one %d or similar)
86 * \param i integer value to be put into error message (%d in output)
87 */
88void* Malloci(size_t size, const char* output, int i)
89{
90 char dummyoutput[MAXDUMMYSTRING];
91 void* dummy = (void *) malloc(size);
92 if (!dummy) {
93 sprintf(dummyoutput,output,i);
94 Error(MallocError, dummyoutput);
95 }
96 return dummy;
97}
98
99/** Malloc with error check and 2 ints.
100 * malloc() wrapper, printing error on null pointer
101 * \param size size of memory to be allocated
102 * \param output error message to be given on failure (containing two %d or similar)
103 * \param i first integer value to be put into error message (%d in output)
104 * \param j second integer value to be put into error message (%d in output)
105 */
106void* Mallocii(size_t size, const char* output, int i, int j)
107{
108 char dummyoutput[MAXDUMMYSTRING];
109 void* dummy = (void *) malloc(size);
110 if (!dummy) {
111 sprintf(dummyoutput,output,i,j);
112 Error(MallocError, dummyoutput);
113 }
114 return dummy;
115}
116
117/** Change size of allocated memory range.
118 * Wrapper for realloc(), giving error message on failure
119 * \param pointer points to allocated memory
120 * \param size new desired size
121 * \param output error message on failure
122 */
123void* Realloc(void* pointer, size_t size, const char* output)
124{
125 void *dummy = (void *) realloc(pointer, size);
126 if (!dummy)
127 Error(MallocError, output);
128 return dummy;
129}
130
131/** Change size of allocated memory range, 1 int in error msg.
132 * Wrapper for realloc(), giving error message on failure
133 * \param pointer points to allocated memory
134 * \param size new desired size
135 * \param output error message on failure (containing one %d or similar)
136 * \param i integer in error message
137 */
138void* Realloci(void* pointer, size_t size, const char* output, int i)
139{
140 char dummyoutput[MAXDUMMYSTRING];
141 void *dummy = (void *) realloc(pointer, size);
142 if (!dummy) {
143 sprintf(dummyoutput, output, i);
144 Error(MallocError, dummyoutput);
145 }
146 return dummy;
147}
148
149/** Change size of allocated memory range, 2 int in error msg.
150 * Wrapper for realloc(), giving error message on failure
151 * \param pointer points to allocated memory
152 * \param size new desired size
153 * \param output error message on failure (containing two %d or similar)
154 * \param i first integer in error message
155 * \param j second integer in error message
156 */
157void* Reallocii(void* pointer, size_t size, const char* output, int i, int j)
158{
159 char dummyoutput[MAXDUMMYSTRING];
160 void *dummy = (void *) realloc(pointer, size);
161 if (!dummy) {
162 sprintf(dummyoutput,output,i,j);
163 Error(MallocError, dummyoutput);
164 }
165 return dummy;
166}
167
168/** Free memory with error check.
169 * Wrapper for free(), free is only called on given non-null pointer
170 * \param *ptr pointer to allocated memory region
171 */
172void Free (void *ptr) {
173 if (ptr) free(ptr);
174 else fprintf(stderr,"Free failure\n");
175}
176
177/** Translates a given integer into color code
178 * The value is interpreted by powers of the range into an rgb set of
179 * values.
180 * \param i specifies value within the range
181 * \param max specifies color range
182 * \param rgb pointer to double[3]
183 */
184void GetRGB(int i, unsigned int max, double* rgb) {
185 int basis,basis2,basis3;
186 int maxRGB,RGBint;
187 int rgbint[3];
188 i++;
189 if (max <= 1) max = 2; /* keine Division durch 0 */
190 basis = ceil(pow((double)(max+1),1./3.));
191 basis2 = basis*basis;
192 basis3 = basis2*basis;
193 maxRGB = basis3-1;
194 /* Koordinatentrans von 1..max -> 1..maxRGB */
195 RGBint = floor(1. + (double)(maxRGB - 1)/(double)(max-1)*(double)(i-1));
196 /* Transferiere RGBint jetzt in Basisdarstellung */
197 rgbint[2] = RGBint/basis2;
198 RGBint %= basis2;
199 rgbint[1] = RGBint/basis;
200 rgbint[0] = RGBint%basis;
201 /* Jetzt Basisdarstellung in rgb darstellung */
202 rgb[2] = rgbint[2]*(1./(basis-1));
203 rgb[1] = rgbint[1]*(1./(basis-1));
204 rgb[0] = rgbint[0]*(1./(basis-1));
205}
206
207/** Waits for other processes to finish.
208 * Simply waits until all processes reach this routine for the MPI_Gather to work
209 * \param *P Problem at hand
210 * \param out 1 - output ready note, 0 - no output
211 */
212void WaitForOtherProcs(struct Problem *P, int out) {
213 /* Warte, bis alle fertig sind! */
214 int buffint = 0;
215 MPI_Gather(&buffint, 0, MPI_INT, &buffint, 0, MPI_INT, 0, P->Par.comm);
216 if(out && P->Call.out[MinOut]) fprintf(stderr,"\nAll procs ready: %i\n",P->Par.me);
217}
218
219/** Initialization for parallel computing.
220 * determines process ids and defines mpi groups (aka Communicators), being
221 * the ones working on the same Psi (when doing fft) and those working on the
222 * same section (transposed GramSchmidt)
223 * \param *P Problem at hand
224 * \param **argv is actually unnecessary
225 */
226void StartParallel (struct Problem *P, char **argv) {
227 int info;
228 char processor_name[MPI_MAX_PROCESSOR_NAME];
229 char dummy[MAXDUMMYSTRING];
230 P->Par.procs = P->Par.proc[PEPsi]*P->Par.proc[PEGamma];
231 P->Par.me = -1; /* eigene Position noch unklar */
232 /* MPI Initialisierung */
233 argv = argv; /* wird nicht benoetigt */
234 /* mpi Gruppen definieren */
235 P->Par.world = MPI_COMM_WORLD;
236 MPI_Comm_dup(P->Par.world, &P->Par.comm);
237 MPI_Comm_size(P->Par.comm, &info);
238 if (info != P->Par.procs) {
239 sprintf(dummy,"StartParallel. Wrong number of processes started %i != %i",info, P->Par.procs);
240 Error(SomeError, dummy);
241 }
242 MPI_Comm_rank(P->Par.comm, &P->Par.mytid);
243 MPI_Get_processor_name(processor_name, &info);
244 P->Par.me = P->Par.mytid;
245 P->Par.mypos[PEGamma] = P->Par.me % P->Par.proc[PEGamma];
246 P->Par.mypos[PEPsi] = P->Par.me / P->Par.proc[PEGamma];
247 if(P->Call.out[NormalOut]) fprintf(stderr,"Process %d(%i,%i) on %s \n", P->Par.mytid, P->Par.mypos[PEPsi], P->Par.mypos[PEGamma], processor_name);
248 if (P->Par.me == 0) { /* Master */
249 if (P->Par.procs > 9999)
250 fprintf(stderr, "(%d)Warning: procs>9999 will cause trouble with output files\n", P->Par.mytid);
251 }
252 if(P->Call.out[MinOut]) fprintf(stderr,"Info: %i processes started\n", P->Par.procs); /* Prozesse gestartet */
253
254
255 /* Erstellung der Communicatoren */
256 switch (P->Lat.Psi.Use) {
257 case UseSpinDouble:
258 P->Par.my_color_comm_ST = (int)SpinDouble;
259 P->Par.me_comm_ST = P->Par.me;
260 P->Par.Max_my_color_comm_ST = 1;
261 P->Par.Max_me_comm_ST = P->Par.procs;
262 break;
263 case UseSpinUpDown:
264 P->Par.my_color_comm_ST = P->Par.me / (P->Par.procs/2);
265 P->Par.me_comm_ST = P->Par.me % (P->Par.procs/2);
266 P->Par.Max_my_color_comm_ST = 2;
267 P->Par.Max_me_comm_ST = P->Par.procs/2;
268 break;
269 }
270 MPI_Comm_split (P->Par.comm, P->Par.my_color_comm_ST, P->Par.me_comm_ST, &P->Par.comm_ST);
271 if (P->Lat.Psi.Use == UseSpinUpDown) {
272 MPI_Intercomm_create ( P->Par.comm_ST, 0, P->Par.comm,
273 (P->Par.my_color_comm_ST ? 0 : P->Par.procs/2)
274 , InterTag1, &P->Par.comm_STInter);
275 }
276
277 /* Alle Procs mit gleichen Psis (Sind alle an einer fft beteiligt)*/
278 P->Par.my_color_comm_ST_Psi = P->Par.me_comm_ST / P->Par.proc[PEGamma];
279 P->Par.me_comm_ST_Psi = P->Par.me_comm_ST % P->Par.proc[PEGamma];
280 P->Par.Max_my_color_comm_ST_Psi = P->Par.Max_me_comm_ST/P->Par.proc[PEGamma];
281 P->Par.Max_me_comm_ST_Psi = P->Par.proc[PEGamma];
282 MPI_Comm_split (P->Par.comm_ST, P->Par.my_color_comm_ST_Psi, P->Par.me_comm_ST_Psi, &P->Par.comm_ST_Psi);
283
284 /* Alle Procs mit gleichen PsisAbschnitt (Transposed Psi - GramSch)*/
285 P->Par.my_color_comm_ST_PsiT = P->Par.me_comm_ST % P->Par.proc[PEGamma];
286 P->Par.me_comm_ST_PsiT = P->Par.me_comm_ST / P->Par.proc[PEGamma];
287 P->Par.Max_my_color_comm_ST_PsiT = P->Par.proc[PEGamma];
288 P->Par.Max_me_comm_ST_PsiT = P->Par.Max_me_comm_ST/P->Par.proc[PEGamma];
289 MPI_Comm_split (P->Par.comm_ST, P->Par.my_color_comm_ST_PsiT, P->Par.me_comm_ST_PsiT, &P->Par.comm_ST_PsiT);
290}
291
292
293/** Removes everything from memory.
294 * Frees memory and exits program
295 * \param *P Problem at hand
296 */
297void RemoveEverything(struct Problem *P)
298{
299 struct Lattice *Lat = &P->Lat;
300 struct Psis *Psi = &Lat->Psi;
301 int i,d, type;
302 if (P->Call.out[NormalOut]) fprintf(stderr,"(%i)RemoveEverything !\n",P->Par.me);
303 //debug(P,"RemoveGradients");
304 RemoveGradients(P, &P->Grad);
305 //debug(P,"RemovePseudoRead");
306 RemovePseudoRead(P);
307 //debug(P,"RemoveIonsRead");
308 RemoveIonsRead(&P->Ion);
309 //debug(P,"fft_3d_destroy_plan");
310 fft_3d_destroy_plan(P,P->Lat.plan);
311 //debug(P,"P->Files.PosTemp");
312 if (P->Files.MeOutVis) {
313 Free(P->Files.PosTemp);
314 }
315 //debug(P,"P->Files.OutputPosType");
316 if (P->Files.MeOutVis)
317 Free(P->Files.OutputPosType);
318 //debug(P,"mainname");
319 Free(P->Files.mainname);
320 //debug(P,"mainpath");
321 Free(P->Files.mainpath);
322 //debug(P,"MainParameterFile");
323 Free(P->Call.MainParameterFile);
324 //debug(P,"MaxNoOfnFields");
325 Free(Lat->MaxNoOfnFields);
326 for (i=0; i < P->Lat.MaxLevel; i++) {
327 //debug(P,"AllMaxG");
328 Free(Lat->Lev[i].AllMaxG);
329 //debug(P,"NFields");
330 Free(Lat->NFields[i]);
331 //debug(P,"GArray");
332 Free(Lat->Lev[i].GArray);
333 //debug(P,"HashG");
334 Free(Lat->Lev[i].HashG);
335 //debug(P,"DoubleG");
336 if (Lat->Lev[i].MaxDoubleG)
337 Free(Lat->Lev[i].DoubleG);
338 if (i != 0) {
339 Free(Lat->Lev[i].PosFactorUp);
340 } else {
341 for (d=0; d < (P->R.DoPerturbation == 1 ? MaxDensityTypes : MaxInitDensityTypes); d++) {
342 //debug(P,"DensityArray");
343 if (Lat->Lev[i].Dens->DensityArray[d] != NULL) Free(Lat->Lev[i].Dens->DensityArray[d]);
344 //debug(P,"DensityCArray");
345 if (Lat->Lev[i].Dens->DensityCArray[d] != NULL) Free(Lat->Lev[i].Dens->DensityCArray[d]);
346 }
347 }
348 /* if (i != Lat->MaxLevel-1) */
349 //debug(P,"Lat->Lev[i].Dens");
350 Free(Lat->Lev[i].Dens);
351 }
352 for (i=1; i < Lat->MaxLevel; i++) {
353 Free(Lat->Lev[i].LPsi->LocalPsi);
354 //debug(P,"LocalPsi");
355 Free(Lat->Lev[i].LPsi->OldLocalPsi);
356 //debug(P,"OldLocalPsi");
357 if (i == 1) {
358 Free(Lat->Lev[i].LPsi->PsiDat);
359 //debug(P,"OldLocalPsi");
360 Free(Lat->Lev[i].LPsi->OldPsiDat);
361 //debug(P,"OldPsiDat");
362 }
363 Free(Lat->Lev[i].LPsi);
364 //debug(P,"LPsi");
365 }
366 for (i=0;i<Lat->Psi.NoOfTotalPsis;i++) {
367 Free(Psi->lambda[i]);
368 //debug(P,"lambda");
369 }
370 for (i=0;i<Lat->Psi.NoOfPsis;i++) {
371 Free(Psi->Overlap[i]);
372 //debug(P,"Overlap");
373 }
374 Free(Psi->lambda);
375 //debug(P,"lambda");
376 Free(Psi->Overlap);
377 //debug(P,"Overlap");
378 Free(Psi->AllPsiStatus);
379 //debug(P,"AllPsiStatus");
380 Free(Psi->AllPsiStatusForSort);
381 //debug(P,"AllPsiStatusForSort");
382 Free(Psi->LocalPsiStatus);
383 //debug(P,"LocalPsiStatus");
384 Free(Psi->AllLocalNo);
385 //debug(P,"AllLocalNo");
386 Free(Psi->RealAllLocalNo);
387 //debug(P,"RealAllLocalNo");
388 Free(Psi->TempSendA);
389 //debug(P,"TempSendA");
390 Free(Psi->AddData);
391 //debug(P,"AddData");
392 Free(Psi->AllActualLocalPsiNo);
393 //debug(P,"AllActualLocalPsiNo");
394 Free(Psi->AllOldActualLocalPsiNo);
395 //debug(P,"AllOldActualLocalPsiNo");
396 Free(Lat->Lev);
397 //debug(P,"Lev");
398 Free(Lat->LevelSizes);
399 //debug(P,"LevelSizes");
400 Free(Lat->NFields);
401 //debug(P,"NFields");
402 if (Lat->RT.Use == UseRT) {
403 Free(Lat->RT.Coeff);
404 Free(Lat->RT.RTLaplaceS);
405 Free(Lat->RT.RTLaplace0);
406 for (i=0; i< MAXRTPOSFAC; i++) Free(Lat->RT.PosFactor[i]);
407 for (i=0; i< MAXRTARRAYS; i++) {
408 Free(Lat->RT.DensityC[i]);
409 }
410 Free(Lat->RT.TempC);
411 }
412 for (type=Occupied;type<Extra;type++)
413 for (i=0; i<MAXALLPSIENERGY; i++) {
414 Free(Lat->Energy[type].PsiEnergy[i]);
415 }
416 for (i=Occupied;i<Extra;i++)
417 Free(P->R.MinimisationName[i]);
418 Free(P->R.MinimisationName);
419 //debug(P,"PsiEnergy");
420 MPI_Comm_free(&P->Par.comm_ST_PsiT);
421 //debug(P,"comm_ST_PsiT");
422 MPI_Comm_free(&P->Par.comm_ST_Psi);
423 //debug(P,"comm_ST_Psi");
424 if (Psi->Use == UseSpinUpDown) MPI_Comm_free(&P->Par.comm_STInter);
425 MPI_Comm_free(&P->Par.comm_ST);
426 //debug(P,"comm_ST");
427 MPI_Comm_free(&P->Par.comm);
428 //debug(P,"comm");
429 Free(P);
430 FreeMPI_OnePsiElement();
431
432 // Free string names from Files structure
433 Free(P->Files.filename);
434 Free(P->Files.default_path);
435 Free(P->Files.pseudopot_path);
436}
437
438static const char suffixspeed[] = ".speed"; //!< suffix of the FileData#SpeedFile where the timings are written to
439
440
441/** Initializes the timer array.
442 * Sets every time, average, min/max and deviation to zero.
443 * SpeedStep is set to 1.
444 * Opens Filedata::SpeedFile for appended writing
445 * \param *P Problem at hand
446 */
447void InitSpeedMeasure(struct Problem *P)
448{
449 struct FileData *F = &P->Files;
450 struct SpeedStruct *S = &P->Speed;
451 int i;
452 F->SpeedFile = NULL;
453 if (P->Par.me == 0)
454 OpenFile(P, &F->SpeedFile, suffixspeed, "a",P->Call.out[ReadOut]);
455 for (i=0; i < MAXTIMETYPES; i++)
456 S->SpeedStep[i] = 1;
457 SetArrayToDouble0(S->time1,MAXTIMETYPES);
458 SetArrayToDouble0(S->time2,MAXTIMETYPES);
459 SetArrayToDouble0(S->time,MAXTIMETYPES);
460 SetArrayToDouble0(S->average,MAXTIMETYPES);
461 SetArrayToDouble0(S->min,MAXTIMETYPES);
462 SetArrayToDouble0(S->max,MAXTIMETYPES);
463 SetArrayToDouble0(S->stddev,MAXTIMETYPES);
464 S->InitSteps = 0;
465 S->LevUpSteps = 0;
466 S->Steps = 0;
467}
468
469/** Measure speed of a routine.
470 * Points to SpeedStruct of the Problem, gets current time and depending on
471 * \a TOT (whether we start or stop the watch) and the timing group \a TT
472 * puts time in SpeedStruct::time1 (start) or in SpeedStruct::time2 (stop)
473 * and in SpeedStruct::time the difference between the two is added.
474 * \param *P Problem at hand containing SpeedStruct
475 * \param TT TimeTypes
476 * \param TOT TimeDotypes
477 */
478void SpeedMeasure(struct Problem *P, enum TimeTypes TT, enum TimeDoTypes TOT)
479{
480 struct SpeedStruct *S = &P->Speed;
481 double timeA = GetTime();
482 switch (TOT) {
483 case StartTimeDo:
484 S->time1[TT] = timeA;
485 break;
486 case StopTimeDo:
487 S->time2[TT] = timeA;
488 S->time[TT] += (S->time2[TT]-S->time1[TT]);
489 break;
490 }
491}
492
493/** Final Measuring and overall time.
494 * Does the last measurement calculation and combines results from all processes
495 * to calculate min, max, average and writes it to FileData::SpeedFile
496 * \param *P Problem at hand
497 */
498void CompleteSpeedMeasure(struct Problem *P)
499{ /* gibt letzte Messung aus und benoetigte Gesamtzeit */
500 struct SpeedStruct *S = &P->Speed;
501 struct FileData *F = &P->Files;
502 struct Lattice *Lat = &P->Lat;
503 struct Psis *Psi = &Lat->Psi;
504 struct RunStruct *R = &P->R;
505 struct Ions *I = &P->Ion;
506 double average[MAXTIMETYPES];
507 double stddev[MAXTIMETYPES];
508 double time[MAXTIMETYPES];
509 int i;
510 S->InitSteps += S->LevUpSteps;
511 for (i=0; i<MAXTIMETYPES; i++)
512 switch ((enum TimeTypes)i) {
513 case InitSimTime:
514 case InitGramSchTime:
515 case InitLocTime:
516 case InitNonLocTime:
517 case InitDensityTime:
518 case LocFTime:
519 case NonLocFTime:
520 case EwaldTime:
521 case GapTime:
522 S->SpeedStep[i] = S->InitSteps;
523 break;
524 case SimTime:
525 case GramSchTime:
526 case LocTime:
527 case NonLocTime:
528 case DensityTime:
529 case WannierTime:
530 case ReadnWriteTime:
531 S->SpeedStep[i] = S->Steps*P->Par.proc[0]/(double)P->Lat.Psi.GlobalNo[PsiMaxNo];
532 break;
533 default:
534 S->SpeedStep[i] = 1;
535 }
536 S->time[LevSMaxG] = R->LevS->MaxG;
537 MPI_Allreduce( S->time, time, MAXTIMETYPES, MPI_DOUBLE, MPI_SUM, P->Par.comm);
538 for (i=0; i<MAXTIMETYPES; i++)
539 time[i] /= (double)P->Par.procs;
540 time[LevSMaxG] = R->LevS->TotalAllMaxG;
541 for (i=0; i<MAXTIMETYPES; i++)
542 average[i] = S->time[i]/S->SpeedStep[i];
543 MPI_Allreduce( average, S->average, MAXTIMETYPES, MPI_DOUBLE, MPI_SUM, P->Par.comm);
544 for (i=0; i<MAXTIMETYPES; i++)
545 S->average[i] /= (double)P->Par.procs;
546 S->average[LevSMaxG] = R->LevS->TotalAllMaxG/(double)P->Par.proc[1];
547 for (i=0; i<MAXTIMETYPES; i++)
548 stddev[i] = (average[i]-S->average[i])*(average[i]-S->average[i]);
549 MPI_Allreduce( stddev, S->stddev, MAXTIMETYPES, MPI_DOUBLE, MPI_SUM, P->Par.comm);
550 MPI_Allreduce( &stddev[LevSMaxG], &S->stddev[LevSMaxG], 1, MPI_DOUBLE, MPI_SUM, P->Par.comm_ST_Psi);
551 for (i=0; i<MAXTIMETYPES-1; i++)
552 S->stddev[i] /= (double)P->Par.procs;
553 S->stddev[LevSMaxG] /= (double)P->Par.proc[1];
554 for (i=0; i<MAXTIMETYPES; i++)
555 S->stddev[i] = sqrt(S->stddev[i]);
556
557 MPI_Allreduce( average, S->max, MAXTIMETYPES, MPI_DOUBLE, MPI_MAX, P->Par.comm);
558 MPI_Allreduce( average, S->min, MAXTIMETYPES, MPI_DOUBLE, MPI_MIN, P->Par.comm);
559 if (P->Par.me != 0) return;
560
561 fprintf(F->SpeedFile, "LevNo\tMaxG\tRMaxG\tMaxN\tN[0]\tN[1]\tN[2]\tRLevSStep\n");
562 for (i=0; i < Lat->MaxLevel; i++)
563 fprintf(F->SpeedFile, "%i\t%i\t%i\t%i\t%i\t%i\t%i\t%i\n", Lat->Lev[i].LevelNo, Lat->Lev[i].TotalAllMaxG, Lat->Lev[i].TotalRealAllMaxG, Lat->Lev[i].MaxN, Lat->Lev[i].N[0], Lat->Lev[i].N[1], Lat->Lev[i].N[2], Lat->Lev[i].Step);
564 fprintf(F->SpeedFile, "procs\tproc[0]\tproc[1]\tPsiMax\tPsiDoub\tPsiUp\tPsiDown\tNRStep\tTotalIons\n");
565 fprintf(F->SpeedFile, "%i\t%i\t%i\t%i\t%i+%i\t%i+%i\t%i+%i\t%i\t%i\n", P->Par.procs, P->Par.proc[0], P->Par.proc[1], Psi->GlobalNo[PsiMaxNo], Psi->GlobalNo[PsiMaxNoDouble], Psi->GlobalNo[PsiMaxAdd], Psi->GlobalNo[PsiMaxNoUp], Psi->GlobalNo[PsiMaxAdd], Psi->GlobalNo[PsiMaxNoDown], Psi->GlobalNo[PsiMaxAdd], R->NewRStep, I->Max_TotalIons);
566
567 fprintf(F->SpeedFile, "Type\tSimTime\t\tInitSimTime\tInitTime\tInitGramSchTime\tInitLocTime\tInitNonLocTime\tInitDensTime\tGramSchTime\tLocTime\t\tNonLocTime\tDensTime\tLocFTime\tNonLocFTime\tEwaldTime\tGapTime\tCurrDensTime\tWannierTime\tReadnWriteTime\tLevSMaxG\n");
568 fprintf(F->SpeedFile, "Steps");
569 for(i=0;i<MAXTIMETYPES;i++)
570 fprintf(F->SpeedFile, "\t%e", S->SpeedStep[i]);
571 fprintf(F->SpeedFile, "\n");
572
573 fprintf(F->SpeedFile, "total");
574 for(i=0;i<MAXTIMETYPES;i++)
575 fprintf(F->SpeedFile, "\t%e", time[i]);
576 fprintf(F->SpeedFile, "\n");
577
578 fprintf(F->SpeedFile, "average");
579 for(i=0;i<MAXTIMETYPES;i++)
580 fprintf(F->SpeedFile, "\t%e", S->average[i]);
581 fprintf(F->SpeedFile, "\n");
582
583 fprintf(F->SpeedFile, "stddev");
584 for(i=0;i<MAXTIMETYPES;i++)
585 fprintf(F->SpeedFile, "\t%e", S->stddev[i]);
586 fprintf(F->SpeedFile, "\n");
587
588 fprintf(F->SpeedFile, "min");
589 for(i=0;i<MAXTIMETYPES;i++)
590 fprintf(F->SpeedFile, "\t%e", S->min[i]);
591 fprintf(F->SpeedFile, "\n");
592
593 fprintf(F->SpeedFile, "max");
594 for(i=0;i<MAXTIMETYPES;i++)
595 fprintf(F->SpeedFile, "\t%e", S->max[i]);
596 fprintf(F->SpeedFile, "\n");
597
598 fclose(F->SpeedFile);
599}
Note: See TracBrowser for help on using the repository browser.