source: pcp/src/helpers.c@ 4aef8a

Last change on this file since 4aef8a was 79290f, checked in by Frederik Heber <heber@…>, 17 years ago

config.h is included in each and every file. After trying to compile on JUMP (with xlc).

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