Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Kill SMPE: use visualization instead.
[simgrid.git] / src / smpi / smpi_bench.c
1 /* Copyright (c) 2007, 2009, 2010. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5   * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 #include "private.h"
8 #include "xbt/dict.h"
9 #include "xbt/sysdep.h"
10
11 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_bench, smpi,
12                                 "Logging specific to SMPI (benchmarking)");
13
14 xbt_dict_t allocs = NULL;       /* Allocated on first use */
15 xbt_dict_t samples = NULL;      /* Allocated on first use */
16
17 typedef struct {
18   int count;
19   char data[];
20 } shared_data_t;
21
22 typedef struct {
23   double time;
24   int count;
25   int max;
26   int started;
27 } local_data_t;
28
29 void smpi_bench_destroy(void)
30 {
31   if (allocs) {
32     xbt_dict_free(&allocs);
33   }
34   if (samples) {
35     xbt_dict_free(&samples);
36   }
37 }
38
39 static void smpi_execute_flops(double flops)
40 {
41   smx_host_t host;
42   smx_action_t action;
43   smx_mutex_t mutex;
44   smx_cond_t cond;
45   e_surf_action_state_t state;
46
47   host = SIMIX_host_self();
48   mutex = SIMIX_mutex_init();
49   cond = SIMIX_cond_init();
50   DEBUG1("Handle real computation time: %f flops", flops);
51   action = SIMIX_action_execute(host, "computation", flops);
52   SIMIX_mutex_lock(mutex);
53   SIMIX_register_action_to_condition(action, cond);
54   for (state = SIMIX_action_get_state(action);
55        state == SURF_ACTION_READY ||
56        state == SURF_ACTION_RUNNING;
57        state = SIMIX_action_get_state(action)) {
58     SIMIX_cond_wait(cond, mutex);
59   }
60   SIMIX_unregister_action_to_condition(action, cond);
61   SIMIX_mutex_unlock(mutex);
62   SIMIX_action_destroy(action);
63   SIMIX_cond_destroy(cond);
64   SIMIX_mutex_destroy(mutex);
65 }
66
67 static void smpi_execute(double duration)
68 {
69   if (duration >= xbt_cfg_get_double(_surf_cfg_set, "smpi/cpu_threshold")) {
70     DEBUG1("Sleep for %f to handle real computation time", duration);
71     smpi_execute_flops(duration *
72                        xbt_cfg_get_double(_surf_cfg_set,
73                                           "smpi/running_power"));
74   }
75 }
76
77 void smpi_bench_begin(void)
78 {
79   xbt_os_timer_start(smpi_process_timer());
80 }
81
82 void smpi_bench_end(void)
83 {
84   xbt_os_timer_t timer = smpi_process_timer();
85
86   xbt_os_timer_stop(timer);
87   smpi_execute(xbt_os_timer_elapsed(timer));
88 }
89
90 unsigned int smpi_sleep(unsigned int secs)
91 {
92   smpi_execute((double) secs);
93   return secs;
94 }
95
96 int smpi_gettimeofday(struct timeval *tv, struct timezone *tz)
97 {
98   double now = SIMIX_get_clock();
99
100   if (tv) {
101     tv->tv_sec = (time_t) now;
102     tv->tv_usec = (suseconds_t) (now * 1e6);
103   }
104   return 0;
105 }
106
107 static char *sample_location(int global, const char *file, int line)
108 {
109   if (global) {
110     return bprintf("%s:%d", file, line);
111   } else {
112     return bprintf("%s:%d:%d", file, line, smpi_process_index());
113   }
114 }
115
116 void smpi_sample_1(int global, const char *file, int line, int max)
117 {
118   char *loc = sample_location(global, file, line);
119   local_data_t *data;
120
121   smpi_bench_end();     /* Take time from previous MPI call into account */
122   if (!samples) {
123     samples = xbt_dict_new();
124   }
125   data = xbt_dict_get_or_null(samples, loc);
126   if (!data) {
127     data = (local_data_t *) xbt_new(local_data_t, 1);
128     data->time = 0.0;
129     data->count = 0;
130     data->max = max;
131     data->started = 0;
132     xbt_dict_set(samples, loc, data, &free);
133   }
134   free(loc);
135 }
136
137 int smpi_sample_2(int global, const char *file, int line)
138 {
139   char *loc = sample_location(global, file, line);
140   local_data_t *data;
141
142   xbt_assert0(samples, "You did something very inconsistent, didn't you?");
143   data = xbt_dict_get_or_null(samples, loc);
144   if (!data) {
145     xbt_assert0(data, "Please, do thing in order");
146   }
147   if (!data->started) {
148     if (data->count < data->max) {
149       data->started = 1;
150       data->count++;
151     } else {
152       DEBUG1("Perform some wait of %f", data->time / (double) data->count);
153       smpi_execute(data->time / (double) data->count);
154     }
155   } else {
156     data->started = 0;
157   }
158   free(loc);
159   smpi_bench_begin();
160   smpi_process_simulated_start();
161   return data->started;
162 }
163
164 void smpi_sample_3(int global, const char *file, int line)
165 {
166   char *loc = sample_location(global, file, line);
167   local_data_t *data;
168
169   xbt_assert0(samples, "You did something very inconsistent, didn't you?");
170   data = xbt_dict_get_or_null(samples, loc);
171   if (!data || !data->started || data->count >= data->max) {
172     xbt_assert0(data, "Please, do thing in order");
173   }
174   smpi_bench_end();
175   data->time += smpi_process_simulated_elapsed();
176   DEBUG2("Average mean after %d steps is %f", data->count,
177          data->time / (double) data->count);
178 }
179
180 void smpi_sample_flops(double flops)
181 {
182   smpi_execute_flops(flops);
183 }
184
185 void *smpi_shared_malloc(size_t size, const char *file, int line)
186 {
187   char *loc = bprintf("%s:%d:%zu", file, line, size);
188   shared_data_t *data;
189
190   if (!allocs) {
191     allocs = xbt_dict_new();
192   }
193   data = xbt_dict_get_or_null(allocs, loc);
194   if (!data) {
195     data = (shared_data_t *) xbt_malloc0(sizeof(int) + size);
196     data->count = 1;
197     xbt_dict_set(allocs, loc, data, &free);
198   } else {
199     data->count++;
200   }
201   free(loc);
202   return data->data;
203 }
204
205 void smpi_shared_free(void *ptr)
206 {
207   shared_data_t *data = (shared_data_t *) ((int *) ptr - 1);
208   char *loc;
209
210   if (!allocs) {
211     WARN0("Cannot free: nothing was allocated");
212     return;
213   }
214   loc = xbt_dict_get_key(allocs, data);
215   if (!loc) {
216     WARN1("Cannot free: %p was not shared-allocated by SMPI", ptr);
217     return;
218   }
219   data->count--;
220   if (data->count <= 0) {
221     xbt_dict_remove(allocs, loc);
222   }
223 }