Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Use strtok_r() instead of non reentrant strtok().
[simgrid.git] / contrib / benchmarking_code_block / inject.h
1 /* Copyright (c) 2013-2017. 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 /* Copy to src/include/xbt/ folder  */
8
9 /* Injecting timings for previously benchmarked code blocks */
10
11 /* Use functions from bench.h to benchmark execution time of the desired block,
12  * then Rhist.R script to read all timings and produce histograms
13  * and finally inject.h to inject values instead of executing block*/
14
15 #ifndef __INJECT_H__
16 #define __INJECT_H__
17
18 #include <time.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <unistd.h>
22 #include <string.h>
23 #include "xbt/RngStream.h"
24 #include "xbt/dict.h"
25 #include "xbt/sysdep.h"
26
27 #define MAX_LINE_INJ 10000
28
29 /*
30  * Histogram entry for each measured block
31  * Each entry is guarded inside xbt dictionary which is read from the file */
32 typedef struct xbt_hist {
33   int n;
34   int counts;
35   double mean;
36   double* breaks;
37   double* percentage;
38   char* block_id;
39 } xbt_hist_t;
40
41 extern RngStream get_randgen(void);
42 typedef RngStream (*get_randgen_func_t)(void);
43
44 extern xbt_dict_t get_dict(void);
45 typedef xbt_dict_t (*get_dict_func_t)(void);
46
47 static inline void xbt_inject_init(char *inputfile);
48 static inline void inject_init_starpu(char *inputfile, xbt_dict_t *dict, RngStream *rng);
49
50 static inline double xbt_inject_time(char *key);
51 static inline double xbt_mean_time(char *key);
52 static inline double xbt_hist_time(char *key);
53
54 /* Initializing xbt dictionary for SMPI version, reading xbt_hist_t entries line by line */
55 static inline void xbt_inject_init(char *inputfile)
56 {
57   xbt_dict_t mydict = get_dict();
58   FILE* fpInput     = fopen(inputfile, "r");
59   if (fpInput == NULL)
60     printf("Error while opening the inputfile");
61   fseek(fpInput, 0, 0);
62
63   char line[200];
64   char* key;
65
66   if (fgets(line, 200, fpInput) == NULL)
67     printf("Error input file is empty!"); // Skipping first row
68   while (fgets(line, 200, fpInput) != NULL) {
69     char *saveptr; /* for strtok_r() */
70     key = strtok_r(line, "\t", &saveptr);
71
72     xbt_hist_t* data = xbt_dict_get_or_null(mydict, key);
73     if (data)
74       printf("Error, data with that block_id already exists!");
75
76     data = (xbt_hist_t*)xbt_new(xbt_hist_t, 1);
77
78     data->block_id = key;
79     data->counts   = atoi(strtok_r(NULL, "\t", &saveptr));
80     data->mean     = atof(strtok_r(NULL, "\t", &saveptr));
81     data->n        = atoi(strtok_r(NULL, "\t", &saveptr));
82
83     data->breaks     = (double*)malloc(sizeof(double) * data->n);
84     data->percentage = (double*)malloc(sizeof(double) * (data->n - 1));
85     for (int i        = 0; i < data->n; i++)
86       data->breaks[i] = atof(strtok_r(NULL, "\t", &saveptr));
87     for (int i            = 0; i < (data->n - 1); i++)
88       data->percentage[i] = atof(strtok_r(NULL, "\t", &saveptr));
89
90     xbt_dict_set(mydict, key, data, NULL);
91   }
92   fclose(fpInput);
93 }
94
95 /* Initializing xbt dictionary for StarPU version, reading xbt_hist_t entries line by line */
96 static inline void inject_init_starpu(char *inputfile, xbt_dict_t *dict, RngStream *rng)
97 {
98   *dict                = xbt_dict_new_homogeneous(free);
99   *rng                 = RngStream_CreateStream("Randgen1");
100   unsigned long seed[] = {134, 233445, 865, 2634, 424242, 876541};
101   RngStream_SetSeed(*rng, seed);
102
103   xbt_dict_t mydict = *dict;
104   FILE* fpInput     = fopen(inputfile, "r");
105   if (fpInput == NULL) {
106     printf("Error while opening the inputfile");
107     return;
108   }
109
110   fseek(fpInput, 0, 0);
111
112   char line[MAX_LINE_INJ];
113   char* key;
114
115   if (fgets(line, MAX_LINE_INJ, fpInput) == NULL) {
116     printf("Error input file is empty!"); // Skipping first row
117     fclose(fpInput);
118     return;
119   }
120
121   while (fgets(line, MAX_LINE_INJ, fpInput) != NULL) {
122     char *saveptr; /* for strtok_r() */
123     key = strtok_r(line, "\t", &saveptr);
124
125     xbt_hist_t* data = xbt_dict_get_or_null(mydict, key);
126     if (data)
127       printf("Error, data with that block_id already exists!");
128
129     data             = (xbt_hist_t*)xbt_new(xbt_hist_t, 1);
130     data->block_id   = key;
131     data->counts     = atoi(strtok_r(NULL, "\t", &saveptr));
132     data->mean       = atof(strtok_r(NULL, "\t", &saveptr));
133     data->n          = atoi(strtok_r(NULL, "\t", &saveptr));
134     data->breaks     = (double*)malloc(sizeof(double) * data->n);
135     data->percentage = (double*)malloc(sizeof(double) * (data->n - 1));
136
137     for (int i        = 0; i < data->n; i++)
138       data->breaks[i] = atof(strtok_r(NULL, "\t", &saveptr));
139     for (int i = 0; i < (data->n - 1); i++) {
140       data->percentage[i] = atof(strtok_r(NULL, "\t", &saveptr));
141     }
142
143     xbt_dict_set(mydict, key, data, NULL);
144   }
145   fclose(fpInput);
146 }
147
148 /* Injecting time */
149 static inline double xbt_inject_time(char *key)
150 {
151   return xbt_hist_time(key);
152   // return xbt_mean_time(key);
153 }
154
155 /* Injecting mean value */
156 static inline double xbt_mean_time(char *key)
157 {
158   xbt_dict_t mydict = get_dict();
159   xbt_hist_t* data  = xbt_dict_get_or_null(mydict, key);
160
161   if (!data) {
162     printf("Warning: element with specified key does not exist (%s)\n", key);
163     return 0;
164   }
165
166   return data->mean;
167 }
168
169 /* Injecting random value from the histogram */
170 static inline double xbt_hist_time(char *key)
171 {
172   xbt_dict_t mydict = get_dict();
173   xbt_hist_t* data  = xbt_dict_get_or_null(mydict, key);
174
175   if (!data) {
176     printf("Warning: element with specified key does not exist (%s)\n", key);
177     return 0;
178   }
179
180   /* Choosing random interval of the histogram */
181   RngStream rng_stream = get_randgen();
182   double r             = RngStream_RandU01(rng_stream);
183   int k                = 0;
184   double left          = 0;
185   double right         = 1;
186   for (int i = 0; i < (data->n - 1); i++) {
187     left += (i == 0) ? 0 : data->percentage[i - 1];
188     right += data->percentage[i];
189     if (left < r && r <= right)
190       k = i;
191   }
192
193   /* Choosing random value inside the interval of the histogram */
194   double r2    = RngStream_RandU01(rng_stream);
195   double timer = data->breaks[k] + r2 * (data->breaks[k + 1] - data->breaks[k]);
196
197   return timer;
198 }
199
200 #endif // __INJECT_H__
201