1 |
|
2 |
/* TODO: note if has been initialized, give error only once if not */ |
3 |
|
4 |
#include <stdio.h> |
5 |
#include <string.h> |
6 |
#include <stdlib.h> |
7 |
#include <time.h> |
8 |
#include <search.h> |
9 |
#ifdef _OPENMP |
10 |
#include <omp.h> |
11 |
#endif |
12 |
|
13 |
#include "escript/blocktimer.h" |
14 |
|
15 |
#ifdef PASO_MPI |
16 |
#include "mpi.h" |
17 |
#endif |
18 |
|
19 |
#ifdef BLOCKTIMER |
20 |
static char *g_names[NUM_TIMERS]; /* Names of the timers */ |
21 |
static int g_count[NUM_TIMERS]; /* How many times was the timer incremented? */ |
22 |
static double g_times[NUM_TIMERS]; /* The total time spent in the block */ |
23 |
static double g_start_time; /* Start time for the entire program */ |
24 |
static int g_initialized = 0; /* Has the blocktimer been initialized? */ |
25 |
static int g_end_computed = 0; /* Has the end time been set? */ |
26 |
#endif /* BLOCKTIMER */ |
27 |
|
28 |
void |
29 |
blocktimer_initialize() |
30 |
{ |
31 |
#ifdef BLOCKTIMER |
32 |
int i; |
33 |
|
34 |
for (i=0; i<NUM_TIMERS; i++) { |
35 |
g_names[i] = (char *)NULL; |
36 |
g_times[i] = 0.0; |
37 |
g_count[i] = 0; |
38 |
} |
39 |
|
40 |
if (hcreate(NUM_TIMERS) == 0) { |
41 |
perror("hcreate"); |
42 |
fprintf(stderr, "blocktimer_initialize: Could not initialize hash table\n"); |
43 |
exit(1); |
44 |
} |
45 |
|
46 |
g_initialized = 1; |
47 |
|
48 |
g_start_time = blocktimer_time(); |
49 |
|
50 |
/* Initialize timer for "entire program" to zero so it appears first in the report */ |
51 |
blocktimer_increment("entire program", g_start_time); |
52 |
g_count[0] = 0; /* Reset counter for "entire program" to zero */ |
53 |
#endif /* BLOCKTIMER */ |
54 |
} |
55 |
|
56 |
void |
57 |
blocktimer_increment(char *name, double start_time) |
58 |
{ |
59 |
#ifdef BLOCKTIMER |
60 |
int id; |
61 |
|
62 |
if (!g_initialized) { return; } |
63 |
|
64 |
id = blocktimer_getOrCreateTimerId(name); |
65 |
|
66 |
g_times[id] += blocktimer_time() - start_time; |
67 |
g_count[id] += 1; |
68 |
#endif /* BLOCKTIMER */ |
69 |
} |
70 |
|
71 |
int |
72 |
blocktimer_getOrCreateTimerId(char *name) |
73 |
{ |
74 |
int id=0; |
75 |
#ifdef BLOCKTIMER |
76 |
static int nextId = 0; /* Next timer ID to assign */ |
77 |
ENTRY item, *found_item; |
78 |
|
79 |
if (!g_initialized) { return(0); } |
80 |
|
81 |
/* Has a timer with 'name' already been defined? */ |
82 |
item.key = name; |
83 |
item.data = (void *) NULL; |
84 |
found_item = hsearch(item, FIND); |
85 |
|
86 |
if (found_item != NULL) { /* Already defined so retrieve it from the hash */ |
87 |
/* Return the ID of the entry we found */ |
88 |
int *idTmp = found_item->data; |
89 |
id = *idTmp; |
90 |
} |
91 |
else { /* Not already defined so create one */ |
92 |
/* malloc new int, can't use stack var or all items share same data */ |
93 |
int *idTmp = (int *)malloc(sizeof(int)); |
94 |
/* Enter the new name in the hash */ |
95 |
if (nextId >= NUM_TIMERS) { |
96 |
fprintf(stderr, "blocktimer: exceeded limit of %d timers, increase NUM_TIMERS\n", NUM_TIMERS); |
97 |
exit(1); |
98 |
} |
99 |
*idTmp = nextId++; |
100 |
item.key = name; |
101 |
item.data = (void *) idTmp; |
102 |
hsearch(item, ENTER); |
103 |
id = *idTmp; |
104 |
strncpy(g_names[id], name, strlen(name)); |
105 |
} |
106 |
|
107 |
#endif /* BLOCKTIMER */ |
108 |
return(id); |
109 |
} |
110 |
|
111 |
void |
112 |
blocktimer_reportSortByName() |
113 |
{ |
114 |
#ifdef BLOCKTIMER |
115 |
int i; |
116 |
|
117 |
if (!g_initialized) { return; } |
118 |
|
119 |
if (!g_end_computed) { |
120 |
blocktimer_increment("entire program", g_start_time); |
121 |
g_end_computed = 1; |
122 |
} |
123 |
printf("BlockTimer sorted by name (sorting TBD):\n"); |
124 |
for(i=0; i<NUM_TIMERS; i++) { |
125 |
if (g_names[i] != (char *) NULL) { |
126 |
printf(" %7d %15.2lf %s\n", g_count[i], g_times[i], g_names[i]); |
127 |
} |
128 |
} |
129 |
#endif /* BLOCKTIMER */ |
130 |
} |
131 |
|
132 |
void |
133 |
blocktimer_reportSortByTime() |
134 |
{ |
135 |
#ifdef BLOCKTIMER |
136 |
int i; |
137 |
|
138 |
if (!g_initialized) { return; } |
139 |
|
140 |
if (!g_end_computed) { |
141 |
blocktimer_increment("entire program", g_start_time); |
142 |
g_end_computed = 1; |
143 |
} |
144 |
printf("BlockTimer sorted by time (sorting TBD):\n"); |
145 |
for(i=0; i<NUM_TIMERS; i++) { |
146 |
if (g_names[i] != (char *) NULL) { |
147 |
printf(" %7d %15.2lf seconds for %s\n", g_count[i], g_times[i], g_names[i]); |
148 |
} |
149 |
} |
150 |
#endif /* BLOCKTIMER */ |
151 |
} |
152 |
|
153 |
/* Copied from Paso_timer() */ |
154 |
double |
155 |
blocktimer_time() |
156 |
{ |
157 |
double out=0.0; |
158 |
#ifdef PASO_MPI |
159 |
out = MPI_Wtime(); |
160 |
#else |
161 |
#ifdef _OPENMP |
162 |
out=omp_get_wtime(); |
163 |
#else |
164 |
out=((double) clock())/CLOCKS_PER_SEC; |
165 |
#endif |
166 |
#endif |
167 |
return(out); |
168 |
} |
169 |
|