~ubuntu-branches/ubuntu/utopic/nwchem/utopic

« back to all changes in this revision

Viewing changes to src/tools/ga-5-2/armci/tools/armci_profile.c

  • Committer: Package Import Robot
  • Author(s): Michael Banck, Daniel Leidert, Andreas Tille, Michael Banck
  • Date: 2013-07-04 12:14:55 UTC
  • mfrom: (1.1.2)
  • Revision ID: package-import@ubuntu.com-20130704121455-5tvsx2qabor3nrui
Tags: 6.3-1
* New upstream release.
* Fixes anisotropic properties (Closes: #696361).
* New features include:
  + Multi-reference coupled cluster (MRCC) approaches
  + Hybrid DFT calculations with short-range HF 
  + New density-functionals including Minnesota (M08, M11) and HSE hybrid
    functionals
  + X-ray absorption spectroscopy (XAS) with TDDFT
  + Analytical gradients for the COSMO solvation model
  + Transition densities from TDDFT 
  + DFT+U and Electron-Transfer (ET) methods for plane wave calculations
  + Exploitation of space group symmetry in plane wave geometry optimizations
  + Local density of states (LDOS) collective variable added to Metadynamics
  + Various new XC functionals added for plane wave calculations, including
    hybrid and range-corrected ones
  + Electric field gradients with relativistic corrections 
  + Nudged Elastic Band optimization method
  + Updated basis sets and ECPs 

[ Daniel Leidert ]
* debian/watch: Fixed.

[ Andreas Tille ]
* debian/upstream: References

[ Michael Banck ]
* debian/upstream (Name): New field.
* debian/patches/02_makefile_flags.patch: Refreshed.
* debian/patches/06_statfs_kfreebsd.patch: Likewise.
* debian/patches/07_ga_target_force_linux.patch: Likewise.
* debian/patches/05_avoid_inline_assembler.patch: Removed, no longer needed.
* debian/patches/09_backported_6.1.1_fixes.patch: Likewise.
* debian/control (Build-Depends): Added gfortran-4.7 and gcc-4.7.
* debian/patches/10_force_gcc-4.7.patch: New patch, explicitly sets
  gfortran-4.7 and gcc-4.7, fixes test suite hang with gcc-4.8 (Closes:
  #701328, #713262).
* debian/testsuite: Added tests for COSMO analytical gradients and MRCC.
* debian/rules (MRCC_METHODS): New variable, required to enable MRCC methods.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#if HAVE_CONFIG_H
 
2
#   include "config.h"
 
3
#endif
 
4
 
 
5
/* $Id: armci_profile.c,v 1.8 2005-11-30 10:20:53 vinod Exp $ */
 
6
 
 
7
/**
 
8
 * Profiler can profile the following ARMCI Calls:
 
9
 *    ARMCI_Get,ARMCI_Put,ARMCI_Acc,ARMCI_NbGet,ARMCI_NbPut,ARMCI_NbAcc,
 
10
 *    ARMCI_GetS,ARMCI_PutS,ARMCI_AccS,ARMCI_NbGetS,ARMCI_NbPutS,ARMCI_NbAccS,
 
11
 *    ARMCI_GetV,ARMCI_PutV,ARMCI_AccV,ARMCI_NbGetV,ARMCI_NbPutV,ARMCI_NbAccV,
 
12
 *    ARMCI_Wait, armci_wait_notify
 
13
 *      (NOTE: As armci_notify is same as ARMCI_Put, it is not profiled.)
 
14
 *   
 
15
 * 
 
16
 * Note #1: Right now, only process 0's profile is printed.
 
17
 * Each and every process saves its profile in the correspoding data struture.
 
18
 * Each process prints its profile to an output file armci_profile.<myrank> 
 
19
 * when armci_profile_terminate() is called (called in ARMCI_Finalize()).
 
20
 *
 
21
 * Note #2: By default profiler prints msg ranges 0 to 21. Example: range 10
 
22
 * corresponds to message ranges from 1024 bytes to 2047 bytes.
 
23
 * Message ranges are in the power of 2. for ex:
 
24
 * ------------------------------------
 
25
 *  MSG_RANGE (r)        BYTES (2^r to 2^(r+1)-1)
 
26
 * ------------------------------------
 
27
 *      0                    0-1 
 
28
 *      1                    2-3
 
29
 *      2                    4-7
 
30
 *     ...                   ...
 
31
 *      10                1024-2047 bytes
 
32
 *     ...                   ...
 
33
 *      20                1MB - (2MB-1)
 
34
 *      21                  >= 2MB
 
35
 * -------------------------------------
 
36
 * To increase the message range, set ARMCI_MAX_MSG_RANGE accordingly.
 
37
 *
 
38
 * Note #3: If Stride information needs to be printed, set ARMCI_PRINT_STRIDE.
 
39
 * Stride information is printed in armci_profile_terminate() for a various 
 
40
 * selective message ranges and event types.Modify it according to your needs.
 
41
 *
 
42
 * Note #4: There is no profiling support for non-blocking operations yet!!
 
43
 */
 
44
#define DEBUG_ 
 
45
#if HAVE_STDIO_H
 
46
#   include <stdio.h>
 
47
#endif
 
48
#if HAVE_STDLIB_H
 
49
#   include <stdlib.h>
 
50
#endif
 
51
#if HAVE_STRING_H
 
52
#   include <string.h>
 
53
#endif
 
54
#if HAVE_MATH_H
 
55
#   include <math.h>
 
56
#endif
 
57
#include "armci.h"
 
58
#include "armcip.h"
 
59
#include "armci_profile.h" 
 
60
 
 
61
#ifndef MPI
 
62
#  include "tcgmsg.h"
 
63
#   define MP_TIMER tcg_time
 
64
#else
 
65
#  include "mpi.h"
 
66
#   define MP_TIMER MPI_Wtime
 
67
#endif
 
68
 
 
69
 
 
70
#define ARMCI_PRINT_STRIDE 1
 
71
#define ARMCI_MAX_MSG_RANGE 22 /* 0 to 21 */
 
72
 
 
73
#if ARMCI_PRINT_STRIDE
 
74
 
 
75
# define STRIDE_COUNT 1000
 
76
# define ARMCI_MAX_DIM 7
 
77
 
 
78
  typedef struct armci_stride {
 
79
    int stride_levels;
 
80
    int proc;
 
81
    int count[ARMCI_MAX_DIM];
 
82
    double time;
 
83
  }armci_stride_t;
 
84
 
 
85
  typedef struct giov {
 
86
    int ptr_array_len;
 
87
    int bytes;
 
88
  }giov_t;
 
89
 
 
90
  typedef struct armci_vector {
 
91
    int vec_len;
 
92
    int proc;
 
93
    giov_t *giov;
 
94
    double time;
 
95
  }armci_vector_t;
 
96
 
 
97
#endif
 
98
 
 
99
#define ARMCI_EVENTS 24
 
100
 
 
101
char *gEventName[ARMCI_EVENTS]={
 
102
  "GET", "PUT", "ACC", 
 
103
  "STRIDED GET", "STRIDED PUT", "STRIDED ACC",
 
104
  "VECTOR GET", "VECTOR PUT", "VECTOR ACC",
 
105
  "NBGET", "NBPUT", "NBACC",
 
106
  "STRIDED NBGET", "STRIDED NBPUT", "STRIDED NBACC",
 
107
  "VECTOR NBGET", "VECTOR NBPUT", "VECTOR NBACC",
 
108
  "BARRIER","ARMCI_WAIT","NOTIFY_WAIT",
 
109
  "FENCE", "ALLFENCE", "RMW"
 
110
};
 
111
 
 
112
typedef struct armci_profile {
 
113
  int count;          /* number of times called */
 
114
  double time;  /* total execution time for "count" calls */
 
115
#if ARMCI_PRINT_STRIDE
 
116
  armci_stride_t *stride;
 
117
  armci_vector_t *vector;
 
118
#endif
 
119
}armci_profile_t;
 
120
 
 
121
/* profile get/put/acc for various message ranges (i.e ARMCI_MAX_MSG_RANGE) */
 
122
static armci_profile_t ARMCI_PROF[ARMCI_EVENTS][ARMCI_MAX_MSG_RANGE];
 
123
 
 
124
/* Current event */
 
125
struct event_info {
 
126
  int is_set;
 
127
  int event_type;
 
128
  int range;
 
129
  double start_time;
 
130
} gCURRENT_EVNT; 
 
131
 
 
132
static int strided_event(int e) {
 
133
    if (e==ARMCI_PROF_GETS || e==ARMCI_PROF_PUTS || e==ARMCI_PROF_ACCS || 
 
134
        e==ARMCI_PROF_NBGETS || e==ARMCI_PROF_NBPUTS || e==ARMCI_PROF_NBACCS)
 
135
       return 1;
 
136
    return 0;
 
137
}
 
138
 
 
139
void armci_profile_init() {
 
140
    int i,j;
 
141
    if(armci_me==0) {printf("\nProfiling ARMCI - ON\n");fflush(stdout);}
 
142
 
 
143
    gCURRENT_EVNT.is_set = 0;
 
144
 
 
145
    for(i=0; i<ARMCI_EVENTS; i++)
 
146
       for(j=0; j<ARMCI_MAX_MSG_RANGE; j++) {
 
147
          ARMCI_PROF[i][j].count = 0; ARMCI_PROF[i][j].time = 0.0; 
 
148
       }
 
149
 
 
150
#if ARMCI_PRINT_STRIDE
 
151
    for(i=0; i<ARMCI_EVENTS; i++) {
 
152
       if(strided_event(i))
 
153
          for(j=0; j<ARMCI_MAX_MSG_RANGE; j++) {
 
154
             ARMCI_PROF[i][j].stride = (armci_stride_t*)malloc(STRIDE_COUNT*sizeof(armci_stride_t));
 
155
             ARMCI_PROF[i][j].vector = NULL;
 
156
             if( ARMCI_PROF[i][j].stride == NULL)
 
157
                armci_die("armci_profile_init(): malloc failed", armci_me);
 
158
          }
 
159
       if(i==ARMCI_PROF_GETV || i==ARMCI_PROF_PUTV || i==ARMCI_PROF_ACCV ||
 
160
          i==ARMCI_PROF_NBGETV || i==ARMCI_PROF_NBPUTV || i==ARMCI_PROF_NBACCV)
 
161
          for(j=0; j<ARMCI_MAX_MSG_RANGE; j++) {
 
162
             ARMCI_PROF[i][j].vector = (armci_vector_t*)malloc(STRIDE_COUNT*sizeof(armci_vector_t));
 
163
             ARMCI_PROF[i][j].stride = NULL;
 
164
             if( ARMCI_PROF[i][j].vector == NULL)
 
165
                armci_die("armci_profile_init(): malloc failed", armci_me);
 
166
          }
 
167
    }
 
168
#endif
 
169
}
 
170
 
 
171
#define ARMCI_EVENT_CLOSED     0
 
172
#define ARMCI_EVENT_NOTCLOSED -1
 
173
#define ARMCI_EVENT_SET        0
 
174
#define ARMCI_EVENT_NOTSET    -1
 
175
 
 
176
static int armci_profile_set_event(int event_type, int range) {
 
177
#ifdef DEBUG
 
178
    if(SERVER_CONTEXT)
 
179
       printf("\n%d(s):call profile set for %s isset is %d",armci_me,
 
180
                                   gEventName[event_type],gCURRENT_EVNT.is_set);
 
181
    else
 
182
       printf("\n%d:call profile set for %s isset is %d",armci_me,
 
183
                                   gEventName[event_type],gCURRENT_EVNT.is_set);
 
184
    fflush(stdout);
 
185
#endif
 
186
    if(gCURRENT_EVNT.is_set == 0) { /* set an event */
 
187
       gCURRENT_EVNT.is_set     = 1;
 
188
       gCURRENT_EVNT.event_type = event_type;
 
189
       gCURRENT_EVNT.range      = range;
 
190
       gCURRENT_EVNT.start_time = MP_TIMER();
 
191
       return ARMCI_EVENT_SET;
 
192
    }
 
193
    else gCURRENT_EVNT.is_set++; /* event overlap */
 
194
    return ARMCI_EVENT_NOTSET;
 
195
}
 
196
 
 
197
static int armci_profile_close_event(int event_type, int range, double *time, 
 
198
                                     char *name) {
 
199
    
 
200
    int curr_event = gCURRENT_EVNT.event_type;
 
201
#ifdef DEBUG
 
202
    if(SERVER_CONTEXT)
 
203
       printf("\n%d(s):call profile close for %s isset is %d",armci_me,
 
204
                                   gEventName[event_type],gCURRENT_EVNT.is_set);
 
205
    else
 
206
       printf("\n%d:call profile close for %s isset is %d",armci_me,
 
207
                                   gEventName[event_type],gCURRENT_EVNT.is_set);
 
208
    fflush(stdout);
 
209
#endif 
 
210
 
 
211
 
 
212
    if(gCURRENT_EVNT.is_set==1) { /* Yep, there is an event set. So close it.*/
 
213
       /*Check if "profile stop" is called for corresponding "profile start"*/
 
214
       if(event_type != curr_event) {
 
215
          printf( 
 
216
                  "%d: %s: ERROR:Profile started for %s, but stopped for %s\n",
 
217
                  armci_me,name,gEventName[curr_event],gEventName[event_type]);
 
218
          fflush(stdout);
 
219
          armci_die("Profile_stop is called a different event", armci_me); 
 
220
       }
 
221
       
 
222
       *time = MP_TIMER() - gCURRENT_EVNT.start_time;
 
223
       ARMCI_PROF[curr_event][range].time += *time;
 
224
       gCURRENT_EVNT.is_set = 0; /* close the event */
 
225
       return ARMCI_EVENT_CLOSED;
 
226
    }
 
227
    else { /* event overlapping */
 
228
       gCURRENT_EVNT.is_set--;
 
229
       if(gCURRENT_EVNT.is_set<=0) {
 
230
          char *msg="Profile_stop is called before profile_start";
 
231
            printf("%d: %s: ERROR: %s. Event Name = %s\n", armci_me, 
 
232
                    name, msg, gEventName[curr_event]);
 
233
            fflush(stdout);
 
234
            armci_die(" profile_stop is called before profile_start", armci_me);
 
235
       }
 
236
    }
 
237
    return ARMCI_EVENT_NOTCLOSED;
 
238
}
 
239
 
 
240
void armci_profile_start_strided(int count[], int stride_levels, int proc, 
 
241
                                 int event_type) {
 
242
    int i, status, bytes=1, range;
 
243
 
 
244
    if(stride_levels >= ARMCI_MAX_DIM) 
 
245
       armci_die("ARMCI_PROFILE: stride_levels >= ARMCI_MAX_DIM. Increase ARMCI_MAX_DIM.", armci_me);
 
246
 
 
247
    /* find the message range */
 
248
    for(i=0; i<= stride_levels; i++)  bytes *= count[i];
 
249
    if(bytes<=0) range=0;
 
250
    else range = (int) (log((double)bytes)/log(2.0));
 
251
    if(range>=ARMCI_MAX_MSG_RANGE-1) range = ARMCI_MAX_MSG_RANGE-1;
 
252
 
 
253
    /* set the curent event for timer */
 
254
    status = armci_profile_set_event(event_type, range);
 
255
    
 
256
    if(status == ARMCI_EVENT_SET) { /* new event set */
 
257
       /* profile update: i.e. update event count */
 
258
       ARMCI_PROF[event_type][range].count++;
 
259
       
 
260
#      if ARMCI_PRINT_STRIDE 
 
261
          if(strided_event(event_type)) {
 
262
             int idx = ARMCI_PROF[event_type][range].count-1;
 
263
             if(idx<STRIDE_COUNT) {
 
264
                ARMCI_PROF[event_type][range].stride[idx].stride_levels = stride_levels;
 
265
                ARMCI_PROF[event_type][range].stride[idx].proc = proc;
 
266
                for(i=0;i<=stride_levels;i++) {
 
267
                   ARMCI_PROF[event_type][range].stride[idx].count[i]=count[i];
 
268
                }
 
269
             }
 
270
          }
 
271
#      endif
 
272
    }
 
273
    else { /* Do nothing. It is just an event overlap */ }
 
274
}
 
275
 
 
276
void armci_profile_stop_strided(int event_type) {
 
277
    double time;
 
278
    int status, range = gCURRENT_EVNT.range;
 
279
 
 
280
    status = armci_profile_close_event(event_type, range, &time,
 
281
                                       "armci_profile_stop_strided");
 
282
    
 
283
#if ARMCI_PRINT_STRIDE
 
284
    if(status == ARMCI_EVENT_CLOSED) {
 
285
       /* record the time of each strided data transfer */
 
286
       if(strided_event(event_type)) {
 
287
          int idx = ARMCI_PROF[event_type][range].count-1;
 
288
          if(idx<STRIDE_COUNT) 
 
289
             ARMCI_PROF[event_type][range].stride[idx].time = time;
 
290
       }
 
291
    }
 
292
#endif
 
293
}
 
294
 
 
295
void armci_profile_start_vector(armci_giov_t darr[], int len, int proc, 
 
296
                                int event_type) {
 
297
 
 
298
    int i, bytes=0, range, status;
 
299
 
 
300
    /* find the message range */
 
301
    for(i=0; i<len; i++) bytes += darr[i].bytes;
 
302
    if(bytes<=0) range=0;
 
303
    else range = (int) (log((double)bytes)/log(2.0));
 
304
    if(range>=ARMCI_MAX_MSG_RANGE-1) range = ARMCI_MAX_MSG_RANGE-1;
 
305
       
 
306
    /* set the curent event for timer */
 
307
    status = armci_profile_set_event(event_type, range);
 
308
 
 
309
    if(status == ARMCI_EVENT_SET) { /* new event set */
 
310
       /* profile update: i.e. update event count */
 
311
       ARMCI_PROF[event_type][range].count++;
 
312
       
 
313
#      if ARMCI_PRINT_STRIDE 
 
314
       {
 
315
          int idx = ARMCI_PROF[event_type][range].count-1;
 
316
          if(idx<STRIDE_COUNT) {
 
317
             ARMCI_PROF[event_type][range].vector[idx].vec_len = len;
 
318
             ARMCI_PROF[event_type][range].vector[idx].proc = proc;
 
319
             ARMCI_PROF[event_type][range].vector[idx].giov = 
 
320
               (giov_t*)malloc(len*sizeof(giov_t));
 
321
             for(i=0;i<len;i++) {
 
322
                ARMCI_PROF[event_type][range].vector[idx].giov[i].ptr_array_len = darr[i].ptr_array_len;
 
323
                ARMCI_PROF[event_type][range].vector[idx].giov[i].bytes = 
 
324
                  darr[i].bytes;
 
325
             }
 
326
          }
 
327
       }
 
328
#      endif
 
329
    }
 
330
}
 
331
 
 
332
void armci_profile_stop_vector(int event_type) {
 
333
    double time;
 
334
    int status, range = gCURRENT_EVNT.range;
 
335
    
 
336
    status = armci_profile_close_event(event_type, range, &time, 
 
337
                                       "armci_profile_stop_vector"); 
 
338
 
 
339
#if ARMCI_PRINT_STRIDE
 
340
    if(status == ARMCI_EVENT_CLOSED) {/*record time of each data transfer*/
 
341
       int idx = ARMCI_PROF[event_type][range].count-1;
 
342
       if(idx<STRIDE_COUNT)  
 
343
          ARMCI_PROF[event_type][range].vector[idx].time = time;
 
344
    }
 
345
#endif
 
346
}
 
347
 
 
348
void armci_profile_start(int event_type) {
 
349
    int range, status;
 
350
 
 
351
    /* message range is zero for events registered using this call */
 
352
    range=0;
 
353
    
 
354
    /* set the curent event for timer */
 
355
    status = armci_profile_set_event(event_type, range);
 
356
    if(status == ARMCI_EVENT_SET) { /* new event set */  
 
357
       /* profile update: i.e. update event count */
 
358
       ARMCI_PROF[event_type][range].count++;
 
359
    }
 
360
}
 
361
 
 
362
void armci_profile_stop(int event_type) {
 
363
    double time;
 
364
    int status,range = gCURRENT_EVNT.range;
 
365
    status = armci_profile_close_event(event_type, range, &time, 
 
366
                                       "armci_profile_stop");
 
367
}
 
368
 
 
369
#define ARMCI_HDR0(fp) fprintf(fp, "\n\n************** TOTAL DATA TRANSFERS **************\n\n");
 
370
#define ARMCI_HDR1(fp) fprintf(fp, "\n\n************ CONTIGUOUS DATA TRANSFER ************\n\n");
 
371
#define ARMCI_HDR2(fp) fprintf(fp, "\n\n********** NON-CONTIGUOUS DATA TRANSFER **********\n\n"); 
 
372
#define ARMCI_HDR3(fp) fprintf(fp, "#gets\t #puts\t #accs\t get_time   put_time   acc_time   RANGE(bytes)\n\n");
 
373
#define ARMCI_HDR4(fp) fprintf(fp, "SL#\tndim\t proc\t time      stride_info\n\n");
 
374
#define ARMCI_HDR5(fp) fprintf(fp, "SL#\tnvec\t proc\t time\t    [ #arrays\t bytes\t]\n");
 
375
#define ARMCI_HDR6(fp) fprintf(fp, "\n\n****** NON-BLOCKING CONTIGUOUS DATA TRANSFER *****\n\n");
 
376
#define ARMCI_HDR7(fp) fprintf(fp, "\n\n*** NON-BLOCKING NON-CONTIGUOUS DATA TRANSFER ****\n\n"); 
 
377
#define ARMCI_HDR8(fp) fprintf(fp, "#gets\t #puts\t #accs\t get_time   put_time   acc_time   RANGE(bytes)\n\n");
 
378
#define ARMCI_HDR9(fp) fprintf(fp, "\n\n******************* ARMCI MISC *******************\n\n");
 
379
 
 
380
/* print profile of all get/put/acc calls for every message range */
 
381
static void armci_print_all(FILE *fp) {
 
382
    int i, nget, nput, nacc, nrange=ARMCI_MAX_MSG_RANGE;
 
383
    double gtime, ptime, atime;
 
384
 
 
385
    ARMCI_HDR0(fp); ARMCI_HDR3(fp);
 
386
    for(i=0; i< nrange; i++) {
 
387
 
 
388
       nget =(ARMCI_PROF[ARMCI_PROF_GET][i].count + 
 
389
              ARMCI_PROF[ARMCI_PROF_GETS][i].count + 
 
390
              ARMCI_PROF[ARMCI_PROF_GETV][i].count +
 
391
              ARMCI_PROF[ARMCI_PROF_NBGET][i].count + 
 
392
              ARMCI_PROF[ARMCI_PROF_NBGETS][i].count + 
 
393
              ARMCI_PROF[ARMCI_PROF_NBGETV][i].count);
 
394
       nput =(ARMCI_PROF[ARMCI_PROF_PUT][i].count + 
 
395
              ARMCI_PROF[ARMCI_PROF_PUTS][i].count + 
 
396
              ARMCI_PROF[ARMCI_PROF_PUTV][i].count +
 
397
              ARMCI_PROF[ARMCI_PROF_NBPUT][i].count +
 
398
              ARMCI_PROF[ARMCI_PROF_NBPUTS][i].count + 
 
399
              ARMCI_PROF[ARMCI_PROF_NBPUTV][i].count);
 
400
       nacc =(ARMCI_PROF[ARMCI_PROF_ACC][i].count + 
 
401
              ARMCI_PROF[ARMCI_PROF_ACCS][i].count + 
 
402
              ARMCI_PROF[ARMCI_PROF_ACCV][i].count +
 
403
              ARMCI_PROF[ARMCI_PROF_NBACC][i].count +
 
404
              ARMCI_PROF[ARMCI_PROF_NBACCS][i].count + 
 
405
              ARMCI_PROF[ARMCI_PROF_NBACCV][i].count);
 
406
 
 
407
       gtime = (ARMCI_PROF[ARMCI_PROF_GET][i].time + 
 
408
                ARMCI_PROF[ARMCI_PROF_GETS][i].time + 
 
409
                ARMCI_PROF[ARMCI_PROF_GETV][i].time +
 
410
                ARMCI_PROF[ARMCI_PROF_NBGET][i].time +
 
411
                ARMCI_PROF[ARMCI_PROF_NBGETS][i].time + 
 
412
                ARMCI_PROF[ARMCI_PROF_NBGETV][i].time);
 
413
       ptime = (ARMCI_PROF[ARMCI_PROF_PUT][i].time + 
 
414
                ARMCI_PROF[ARMCI_PROF_PUTS][i].time + 
 
415
                ARMCI_PROF[ARMCI_PROF_PUTV][i].time +
 
416
                ARMCI_PROF[ARMCI_PROF_NBPUT][i].time +
 
417
                ARMCI_PROF[ARMCI_PROF_NBPUTS][i].time + 
 
418
                ARMCI_PROF[ARMCI_PROF_NBPUTV][i].time);
 
419
       atime = (ARMCI_PROF[ARMCI_PROF_ACC][i].time + 
 
420
                ARMCI_PROF[ARMCI_PROF_ACCS][i].time + 
 
421
                ARMCI_PROF[ARMCI_PROF_ACCV][i].time +
 
422
                ARMCI_PROF[ARMCI_PROF_NBACC][i].time +
 
423
                ARMCI_PROF[ARMCI_PROF_NBACCS][i].time + 
 
424
                ARMCI_PROF[ARMCI_PROF_NBACCV][i].time);
 
425
       
 
426
       fprintf(fp, "%d\t %d\t %d\t %.2e   %.2e   %.2e  ",
 
427
               nget, nput, nacc,  gtime, ptime, atime);
 
428
       if (i< nrange-1) fprintf(fp, "(%d-%d)\n", 1<<i, (1<<(i+1))-1);
 
429
       else fprintf(fp, "(>=%d)\n", 1<<(ARMCI_MAX_MSG_RANGE-1));
 
430
    }
 
431
}
 
432
 
 
433
/* print profile of contiguous get/put/acc calls for every message range */
 
434
static void armci_print_contig(FILE *fp) {
 
435
    int i, nrange=ARMCI_MAX_MSG_RANGE; 
 
436
    ARMCI_HDR1(fp); ARMCI_HDR3(fp);
 
437
    for(i=0; i< nrange; i++) {
 
438
       fprintf(fp, "%d\t %d\t %d\t %.2e   %.2e   %.2e  ",
 
439
               ARMCI_PROF[ARMCI_PROF_GET][i].count,
 
440
               ARMCI_PROF[ARMCI_PROF_PUT][i].count,
 
441
               ARMCI_PROF[ARMCI_PROF_ACC][i].count, 
 
442
               ARMCI_PROF[ARMCI_PROF_GET][i].time,
 
443
               ARMCI_PROF[ARMCI_PROF_PUT][i].time,
 
444
               ARMCI_PROF[ARMCI_PROF_ACC][i].time);
 
445
       if(i< nrange-1) fprintf(fp, "(%d-%d)\n", 1<<i, (1<<(i+1))-1);
 
446
       else fprintf(fp, "(>=%d)\n", 1<<(ARMCI_MAX_MSG_RANGE-1));
 
447
    }
 
448
}
 
449
 
 
450
/* This prints the number of non-contiguous get/put/acc/ calls for every 
 
451
   message range */
 
452
static void armci_print_noncontig(FILE *fp) {
 
453
    int i, nget, nput, nacc, nrange=ARMCI_MAX_MSG_RANGE;
 
454
    double gtime, ptime, atime;
 
455
 
 
456
    ARMCI_HDR2(fp); ARMCI_HDR3(fp);
 
457
    for(i=0; i< nrange; i++) {
 
458
       nget = (ARMCI_PROF[ARMCI_PROF_GETS][i].count + 
 
459
               ARMCI_PROF[ARMCI_PROF_GETV][i].count);
 
460
       nput = (ARMCI_PROF[ARMCI_PROF_PUTS][i].count + 
 
461
               ARMCI_PROF[ARMCI_PROF_PUTV][i].count);
 
462
       nacc = (ARMCI_PROF[ARMCI_PROF_ACCS][i].count + 
 
463
               ARMCI_PROF[ARMCI_PROF_ACCV][i].count);
 
464
       gtime = (ARMCI_PROF[ARMCI_PROF_GETS][i].time + 
 
465
                ARMCI_PROF[ARMCI_PROF_GETV][i].time);
 
466
       ptime = (ARMCI_PROF[ARMCI_PROF_PUTS][i].time + 
 
467
                ARMCI_PROF[ARMCI_PROF_PUTV][i].time);
 
468
       atime = (ARMCI_PROF[ARMCI_PROF_ACCS][i].time + 
 
469
                ARMCI_PROF[ARMCI_PROF_ACCV][i].time);
 
470
       
 
471
       fprintf(fp, "%d\t %d\t %d\t %.2e   %.2e   %.2e  ",
 
472
               nget, nput, nacc,  gtime, ptime, atime);
 
473
       if (i< nrange-1) fprintf(fp, "(%d-%d)\n", 1<<i, (1<<(i+1))-1);
 
474
       else fprintf(fp, "(>=%d)\n", 1<<(ARMCI_MAX_MSG_RANGE-1));
 
475
    }
 
476
}
 
477
 
 
478
/* print profile of non-blocking contiguous get/put/acc calls for every 
 
479
   message range */
 
480
static void armci_print_nbcontig(FILE *fp) {
 
481
    int i, nrange=ARMCI_MAX_MSG_RANGE; 
 
482
    ARMCI_HDR6(fp); ARMCI_HDR8(fp);
 
483
    for(i=0; i< nrange; i++) {
 
484
       fprintf(fp, "%d\t %d\t %d\t %.2e   %.2e   %.2e  ",
 
485
               ARMCI_PROF[ARMCI_PROF_NBGET][i].count,
 
486
               ARMCI_PROF[ARMCI_PROF_NBPUT][i].count,
 
487
               ARMCI_PROF[ARMCI_PROF_NBACC][i].count, 
 
488
               ARMCI_PROF[ARMCI_PROF_NBGET][i].time,
 
489
               ARMCI_PROF[ARMCI_PROF_NBPUT][i].time,
 
490
               ARMCI_PROF[ARMCI_PROF_NBACC][i].time);
 
491
       if(i< nrange-1) fprintf(fp, "(%d-%d)\n", 1<<i, (1<<(i+1))-1);
 
492
       else fprintf(fp, "(>=%d)\n", 1<<(ARMCI_MAX_MSG_RANGE-1));
 
493
    }
 
494
}
 
495
 
 
496
/* This prints the number of non-blocking non-contiguous get/put/acc/ calls 
 
497
   for every message range */
 
498
static void armci_print_nbnoncontig(FILE *fp) {
 
499
    int i, nget, nput, nacc, nrange=ARMCI_MAX_MSG_RANGE;
 
500
    double gtime, ptime, atime;
 
501
 
 
502
    ARMCI_HDR7(fp); ARMCI_HDR8(fp);
 
503
    for(i=0; i< nrange; i++) {
 
504
       nget = (ARMCI_PROF[ARMCI_PROF_NBGETS][i].count + 
 
505
               ARMCI_PROF[ARMCI_PROF_NBGETV][i].count);
 
506
       nput = (ARMCI_PROF[ARMCI_PROF_NBPUTS][i].count + 
 
507
               ARMCI_PROF[ARMCI_PROF_NBPUTV][i].count);
 
508
       nacc = (ARMCI_PROF[ARMCI_PROF_NBACCS][i].count + 
 
509
               ARMCI_PROF[ARMCI_PROF_NBACCV][i].count);
 
510
       gtime = (ARMCI_PROF[ARMCI_PROF_NBGETS][i].time + 
 
511
                ARMCI_PROF[ARMCI_PROF_NBGETV][i].time);
 
512
       ptime = (ARMCI_PROF[ARMCI_PROF_NBPUTS][i].time + 
 
513
                ARMCI_PROF[ARMCI_PROF_NBPUTV][i].time);
 
514
       atime = (ARMCI_PROF[ARMCI_PROF_NBACCS][i].time + 
 
515
                ARMCI_PROF[ARMCI_PROF_NBACCV][i].time);
 
516
 
 
517
       fprintf(fp, "%d\t %d\t %d\t %.2e   %.2e   %.2e  ",
 
518
               nget, nput, nacc,  gtime, ptime, atime);
 
519
       if (i< nrange-1) fprintf(fp, "(%d-%d)\n", 1<<i, (1<<(i+1))-1);
 
520
       else fprintf(fp, "(>=%d)\n", 1<<(ARMCI_MAX_MSG_RANGE-1));
 
521
    }
 
522
}
 
523
 
 
524
/* Profile of armci_notify_wait(), ARMCI_Wait() and ARMCI_Barrier() */
 
525
static void armci_print_misc(FILE *fp) {
 
526
    ARMCI_HDR9(fp);
 
527
    fprintf(fp, "#calls\t time\t   EVENT\n\n");
 
528
    fprintf(fp, "%d\t %.2e  ARMCI_Wait()\n", 
 
529
            ARMCI_PROF[ARMCI_PROF_WAIT][0].count, 
 
530
            ARMCI_PROF[ARMCI_PROF_WAIT][0].time);
 
531
    fprintf(fp, "%d\t %.2e  armci_notify_wait()\n", 
 
532
            ARMCI_PROF[ARMCI_PROF_NOTIFY][0].count, 
 
533
            ARMCI_PROF[ARMCI_PROF_NOTIFY][0].time);
 
534
    fprintf(fp, "%d\t %.2e  ARMCI_Barrier()\n", 
 
535
            ARMCI_PROF[ARMCI_PROF_BARRIER][0].count, 
 
536
            ARMCI_PROF[ARMCI_PROF_BARRIER][0].time);
 
537
    fprintf(fp, "%d\t %.2e  ARMCI_Fence()\n", 
 
538
            ARMCI_PROF[ARMCI_PROF_FENCE][0].count, 
 
539
            ARMCI_PROF[ARMCI_PROF_FENCE][0].time);
 
540
    fprintf(fp, "%d\t %.2e  ARMCI_Allfence()\n", 
 
541
            ARMCI_PROF[ARMCI_PROF_ALLFENCE][0].count, 
 
542
            ARMCI_PROF[ARMCI_PROF_ALLFENCE][0].time);
 
543
    fprintf(fp, "%d\t %.2e  ARMCI_Rmw()\n", 
 
544
            ARMCI_PROF[ARMCI_PROF_RMW][0].count, 
 
545
            ARMCI_PROF[ARMCI_PROF_RMW][0].time);
 
546
}
 
547
 
 
548
#if ARMCI_PRINT_STRIDE 
 
549
static void armci_print_warning_msg(FILE *fp, int range, int str_count) {
 
550
    fprintf(fp, "WARNING: In your program, total number of data transfers\n");
 
551
    fprintf(fp, "for message range[%d - %d] is %d. This exceeds\n", 
 
552
            1<<range, 1<<(range+1), str_count);
 
553
    fprintf(fp,"the maximum # of data transfers [%d] that can be profiled.\n",
 
554
            STRIDE_COUNT); 
 
555
    fprintf(fp, "Therefore profile of only first %d data \n", STRIDE_COUNT);
 
556
    fprintf(fp, "transfers are shown below. To increase the count, set\n");
 
557
    fprintf(fp, "STRIDE_COUNT > %d (in armci_profile.c)\n", str_count);
 
558
}
 
559
 
 
560
static void armci_print_stridedinfo(FILE *fp, int event, int range) {
 
561
    int i, j, stride_levels, str_count;
 
562
    double time=0.0;
 
563
    
 
564
    str_count = ARMCI_PROF[event][range].count;
 
565
    if(str_count <=0) return;    
 
566
    if(str_count > STRIDE_COUNT) { 
 
567
       armci_print_warning_msg(fp, range, str_count);
 
568
       str_count = STRIDE_COUNT;
 
569
    }
 
570
 
 
571
    fprintf(fp, "\n\nSTRIDE INFORMATION FOR MSG_RANGE %d-%d for EVENT: %s\n", 
 
572
            1<<range, (1<<(range+1))-1, gEventName[event]);
 
573
    ARMCI_HDR4(fp);
 
574
 
 
575
    for(i=0; i< str_count; i++) {
 
576
       time += ARMCI_PROF[event][range].stride[i].time;
 
577
       stride_levels  = ARMCI_PROF[event][range].stride[i].stride_levels;
 
578
       fprintf(fp, "%d\t%d\t %d\t %.2e  (",i, stride_levels,
 
579
               ARMCI_PROF[event][range].stride[i].proc,
 
580
               ARMCI_PROF[event][range].stride[i].time);
 
581
       for(j=0;j<=stride_levels;j++) {
 
582
          fprintf(fp, "%d", ARMCI_PROF[event][range].stride[i].count[j]);
 
583
          if(j!=stride_levels) fprintf(fp, "x");
 
584
       }
 
585
       fprintf(fp, ")\n");
 
586
    }
 
587
    /*This o/p is just for verification*/
 
588
    fprintf(fp, "**** STRIDE_COUNT = %d ; TOTAL TIME = %.2e\n",
 
589
            str_count, time);
 
590
}
 
591
 
 
592
static void armci_print_vectorinfo(FILE *fp, int event, int range) {
 
593
    int i, j, vec_len, str_count;
 
594
    double time=0.0;
 
595
    
 
596
    str_count = ARMCI_PROF[event][range].count;
 
597
    if(str_count <=0) return; 
 
598
    if(str_count > STRIDE_COUNT) { 
 
599
       armci_print_warning_msg(fp, range, str_count);
 
600
       str_count = STRIDE_COUNT;
 
601
    }
 
602
    
 
603
    fprintf(fp, "\n\nVECTOR INFORMATION FOR MSG_RANGE %d-%d for EVENT: %s\n", 
 
604
            1<<range, (1<<(range+1))-1, gEventName[event]);
 
605
    ARMCI_HDR5(fp);
 
606
 
 
607
    for(i=0; i< str_count; i++) {
 
608
       time += ARMCI_PROF[event][range].vector[i].time;
 
609
       vec_len  = ARMCI_PROF[event][range].vector[i].vec_len;
 
610
       fprintf(fp, "%d\t%d\t %d\t %.2e   [  ",i, vec_len,
 
611
               ARMCI_PROF[event][range].vector[i].proc,
 
612
               ARMCI_PROF[event][range].vector[i].time);
 
613
       for(j=0;j<vec_len;j++) {
 
614
          fprintf(fp, "%-9d %d\t]\n", 
 
615
                  ARMCI_PROF[event][range].vector[i].giov[j].ptr_array_len,
 
616
                  ARMCI_PROF[event][range].vector[i].giov[j].bytes);
 
617
          if(j!=vec_len-1) fprintf(fp, "\t\t\t\t    [  ");
 
618
       }
 
619
    }
 
620
    /*This o/p is just for verification*/
 
621
    fprintf(fp, "**** STRIDE_COUNT = %d ; TOTAL TIME = %.2e\n",
 
622
            str_count, time);
 
623
}
 
624
#endif /* end of ARMCI_PRINT_STRIDE */
 
625
 
 
626
void armci_profile_terminate() {
 
627
    FILE *fp = stdout;
 
628
    char file_name[50];
 
629
    sprintf(file_name, "armci_profile.%d", armci_me);
 
630
    fp = fopen(file_name, "w");
 
631
 
 
632
    armci_print_all(fp);         /* total get/put/acc calls */
 
633
    armci_print_contig(fp);      /* contiguous calls */
 
634
    armci_print_noncontig(fp);   /* non-contiguous calls */
 
635
    armci_print_nbcontig(fp);    /* non-blocking contiguous calls */
 
636
    armci_print_nbnoncontig(fp); /* non-blocking non-contiguous calls */
 
637
    
 
638
    /* miscellaneous (barrier, armci_wait, notify_wait) */
 
639
    armci_print_misc(fp);
 
640
 
 
641
#if ARMCI_PRINT_STRIDE
 
642
    {
 
643
       /**
 
644
        * printing stride info for non-contiguous get (ARMCI_PROF_GETS) for message
 
645
        * range #6. 2^6 - 2^(6+1) bytes (i.e. 64-128 bytes)
 
646
        *    Ex: armci_print_stridedinfo(ARMCI_PROF_GETS,6);
 
647
        */
 
648
#define ARMCI_PRINT_EVENTS 6
 
649
       int i,j;
 
650
       int str_event[ARMCI_PRINT_EVENTS]={ARMCI_PROF_GETS, ARMCI_PROF_PUTS,
 
651
                                          ARMCI_PROF_ACCS, ARMCI_PROF_NBGETS,
 
652
                                          ARMCI_PROF_NBPUTS,ARMCI_PROF_NBACCS};
 
653
       int vec_event[ARMCI_PRINT_EVENTS]={ARMCI_PROF_GETV, ARMCI_PROF_PUTV,
 
654
                                          ARMCI_PROF_ACCV, ARMCI_PROF_NBGETV,
 
655
                                          ARMCI_PROF_NBPUTV,ARMCI_PROF_NBACCV};
 
656
       
 
657
       fprintf(fp,"\n\n***************************************************\n");
 
658
       fprintf(fp,    " STRIDE INFORMATION for all strided data transfers\n");
 
659
       fprintf(fp,    "***************************************************\n");
 
660
       for(i=0; i<ARMCI_MAX_MSG_RANGE; i++)
 
661
          for(j=0; j<ARMCI_PRINT_EVENTS; j++)
 
662
             armci_print_stridedinfo(fp,str_event[j], i);
 
663
       
 
664
       fprintf(fp,"\n\n**************************************************\n");
 
665
       fprintf(fp,    " VECTOR INFORMATION for all vector data transfers\n");
 
666
       fprintf(fp,    "**************************************************\n");
 
667
       for(i=0; i<ARMCI_MAX_MSG_RANGE; i++)
 
668
          for(j=0; j<ARMCI_PRINT_EVENTS; j++)
 
669
             armci_print_vectorinfo(fp,vec_event[j], i);
 
670
    }
 
671
#endif
 
672
    fclose(fp);
 
673
}