Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Removed unused variables and added missing return call.
[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    if (allocs) {
31       xbt_dict_free(&allocs);
32    }
33    if (samples) {
34       xbt_dict_free(&samples);
35    }
36 }
37
38 static void smpi_execute(double duration) {
39   smx_host_t host;
40   smx_action_t action;
41   smx_mutex_t mutex;
42   smx_cond_t cond;
43   e_surf_action_state_t state;
44
45   if(duration >= xbt_cfg_get_double(_surf_cfg_set, "smpi/cpu_threshold")) {
46     host = SIMIX_host_self();
47     mutex = SIMIX_mutex_init();
48     cond = SIMIX_cond_init();
49     DEBUG1("Sleep for %f to handle real computation time", duration);
50     duration *= xbt_cfg_get_double(_surf_cfg_set, "smpi/running_power");
51     action = SIMIX_action_execute(host, "computation", duration);
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; state = SIMIX_action_get_state(action)) {
57       SIMIX_cond_wait(cond, mutex);
58     }
59     SIMIX_unregister_action_to_condition(action, cond);
60     SIMIX_mutex_unlock(mutex);
61     SIMIX_action_destroy(action);
62     SIMIX_cond_destroy(cond);
63     SIMIX_mutex_destroy(mutex);
64   }
65 }
66
67 void smpi_bench_begin(int rank, const char* mpi_call) {
68   if(mpi_call && rank >= 0 && xbt_cfg_get_int(_surf_cfg_set, "smpi/log_events")) {
69     INFO3("SMPE: ts=%f rank=%d type=end et=%s", SIMIX_get_clock(), rank, mpi_call);
70   }
71   xbt_os_timer_start(smpi_process_timer());
72 }
73
74 void smpi_bench_end(int rank, const char* mpi_call) {
75   xbt_os_timer_t timer = smpi_process_timer();
76
77   xbt_os_timer_stop(timer);
78   smpi_execute(xbt_os_timer_elapsed(timer));
79   if(mpi_call && rank >= 0 && xbt_cfg_get_int(_surf_cfg_set, "smpi/log_events")) {
80     INFO3("SMPE: ts=%f rank=%d type=begin et=%s", SIMIX_get_clock(), rank, mpi_call);
81   }
82 }
83
84 unsigned int smpi_sleep(unsigned int secs) {
85    smpi_execute((double)secs);
86    return secs;
87 }
88
89 int smpi_gettimeofday(struct timeval* tv, struct timezone* tz) {
90    double now = SIMIX_get_clock();
91
92    if(tv) {
93       tv->tv_sec = (time_t)now;
94       tv->tv_usec = (suseconds_t)(now * 1e6);
95    }
96    return 0;
97 }
98
99 static char* sample_location(int global, const char* file, int line) {
100    if(global) {
101       return bprintf("%s:%d", file, line);
102    } else {
103       return bprintf("%s:%d:%d", file, line, smpi_process_index());
104    }
105 }
106
107 void smpi_sample_1(int global, const char* file, int line, int max) {
108    char* loc = sample_location(global, file, line);
109    local_data_t* data;
110
111    smpi_bench_end(-1, NULL); /* Take time from previous MPI call into account */
112    if (!samples) {
113       samples = xbt_dict_new();
114    }
115    data = xbt_dict_get_or_null(samples, loc);
116    if (!data) {
117       data = (local_data_t*)xbt_new(local_data_t, 1);
118       data->time = 0.0;
119       data->count = 0;
120       data->max = max;
121       data->started = 0;
122       xbt_dict_set(samples, loc, data, &free);
123    }
124    free(loc);
125 }
126
127 int smpi_sample_2(int global, const char* file, int line) {
128    char* loc = sample_location(global, file, line);
129    local_data_t* data;
130
131    xbt_assert0(samples, "You did something very inconsistent, didn't you?");
132    data = xbt_dict_get_or_null(samples, loc);
133    if (!data) {
134       xbt_assert0(data, "Please, do thing in order");
135    }
136    if (!data->started) {
137       if (data->count < data->max) {
138          data->started = 1;
139          data->count++;
140       } else {
141          DEBUG1("Perform some wait of %f", data->time / (double)data->count);
142          smpi_execute(data->time / (double)data->count);
143       }
144    } else {
145       data->started = 0;
146    }
147    free(loc);
148    smpi_bench_begin(-1, NULL);
149    smpi_process_simulated_start();
150    return data->started;
151 }
152
153 void smpi_sample_3(int global, const char* file, int line) {
154    char* loc = sample_location(global, file, line);
155    local_data_t* data;
156
157    xbt_assert0(samples, "You did something very inconsistent, didn't you?");
158    data = xbt_dict_get_or_null(samples, loc);
159    if (!data || !data->started || data->count >= data->max) {
160       xbt_assert0(data, "Please, do thing in order");
161    }
162    smpi_bench_end(-1, NULL);
163    data->time += smpi_process_simulated_elapsed();
164    DEBUG2("Average mean after %d steps is %f", data->count, data->time / (double)data->count);
165 }
166
167 void* smpi_shared_malloc(size_t size, const char* file, int line) {
168    char* loc = bprintf("%s:%d:%zu", file, line, size);
169    shared_data_t* data;
170
171    if (!allocs) {
172       allocs = xbt_dict_new();
173    }
174    data = xbt_dict_get_or_null(allocs, loc);
175    if (!data) {
176       data = (shared_data_t*)xbt_malloc0(sizeof(int) + size);
177       data->count = 1;
178       xbt_dict_set(allocs, loc, data, &free);
179    } else {
180       data->count++;
181    }
182    free(loc);
183    return data->data;
184 }
185
186 void smpi_shared_free(void* ptr) {
187    shared_data_t* data = (shared_data_t*)((int*)ptr - 1);
188    char* loc;
189
190    if (!allocs) {
191       WARN0("Cannot free: nothing was allocated");
192       return;
193    }
194    loc = xbt_dict_get_key(allocs, data);
195    if (!loc) {
196       WARN1("Cannot free: %p was not shared-allocated by SMPI", ptr);
197       return;
198    }
199    data->count--;
200    if (data->count <= 0) {
201       xbt_dict_remove(allocs, loc);
202    }
203 }