Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' into xbt_random
[simgrid.git] / contrib / benchmarking_code_block / inject.h
1 /* Copyright (c) 2013-2019. 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   xbt_assert(fpInput != NULL, "Error while opening the inputfile");
60   fseek(fpInput, 0, 0);
61
62   char line[200];
63   char* key;
64
65   if (fgets(line, 200, fpInput) == NULL)
66     printf("Error input file is empty!"); // Skipping first row
67   while (fgets(line, 200, fpInput) != NULL) {
68     char *saveptr = NULL; /* for strtok_r() */
69     key = strtok_r(line, "\t", &saveptr);
70
71     xbt_hist_t* data = xbt_dict_get_or_null(mydict, key);
72     if (data)
73       printf("Error, data with that block_id already exists!");
74
75     data = (xbt_hist_t*)xbt_new(xbt_hist_t, 1);
76
77     data->block_id = key;
78     data->counts   = atoi(strtok_r(NULL, "\t", &saveptr));
79     data->mean     = atof(strtok_r(NULL, "\t", &saveptr));
80     data->n        = atoi(strtok_r(NULL, "\t", &saveptr));
81
82     data->breaks     = (double*)malloc(sizeof(double) * data->n);
83     data->percentage = (double*)malloc(sizeof(double) * (data->n - 1));
84     for (int i        = 0; i < data->n; i++)
85       data->breaks[i] = atof(strtok_r(NULL, "\t", &saveptr));
86     for (int i            = 0; i < (data->n - 1); i++)
87       data->percentage[i] = atof(strtok_r(NULL, "\t", &saveptr));
88
89     xbt_dict_set(mydict, key, data, NULL);
90   }
91   fclose(fpInput);
92 }
93
94 /* Initializing xbt dictionary for StarPU version, reading xbt_hist_t entries line by line */
95 static inline void inject_init_starpu(char *inputfile, xbt_dict_t *dict, RngStream *rng)
96 {
97   *dict                = xbt_dict_new_homogeneous(free);
98   *rng                 = RngStream_CreateStream("Randgen1");
99   unsigned long seed[] = {134, 233445, 865, 2634, 424242, 876541};
100   RngStream_SetSeed(*rng, seed);
101
102   xbt_dict_t mydict = *dict;
103   FILE* fpInput     = fopen(inputfile, "r");
104   if (fpInput == NULL) {
105     printf("Error while opening the inputfile");
106     return;
107   }
108
109   fseek(fpInput, 0, 0);
110
111   char line[MAX_LINE_INJ];
112   char* key;
113
114   if (fgets(line, MAX_LINE_INJ, fpInput) == NULL) {
115     printf("Error input file is empty!"); // Skipping first row
116     fclose(fpInput);
117     return;
118   }
119
120   while (fgets(line, MAX_LINE_INJ, fpInput) != NULL) {
121     char *saveptr = NULL; /* for strtok_r() */
122     key = strtok_r(line, "\t", &saveptr);
123
124     xbt_hist_t* data = xbt_dict_get_or_null(mydict, key);
125     if (data)
126       printf("Error, data with that block_id already exists!");
127
128     data             = (xbt_hist_t*)xbt_new(xbt_hist_t, 1);
129     data->block_id   = key;
130     data->counts     = atoi(strtok_r(NULL, "\t", &saveptr));
131     data->mean       = atof(strtok_r(NULL, "\t", &saveptr));
132     data->n          = atoi(strtok_r(NULL, "\t", &saveptr));
133     data->breaks     = (double*)malloc(sizeof(double) * data->n);
134     data->percentage = (double*)malloc(sizeof(double) * (data->n - 1));
135
136     for (int i        = 0; i < data->n; i++)
137       data->breaks[i] = atof(strtok_r(NULL, "\t", &saveptr));
138     for (int i = 0; i < (data->n - 1); i++) {
139       data->percentage[i] = atof(strtok_r(NULL, "\t", &saveptr));
140     }
141
142     xbt_dict_set(mydict, key, data, NULL);
143   }
144   fclose(fpInput);
145 }
146
147 /* Injecting time */
148 static inline double xbt_inject_time(char *key)
149 {
150   return xbt_hist_time(key);
151   // return xbt_mean_time(key);
152 }
153
154 /* Injecting mean value */
155 static inline double xbt_mean_time(char *key)
156 {
157   xbt_dict_t mydict = get_dict();
158   xbt_hist_t* data  = xbt_dict_get_or_null(mydict, key);
159
160   if (!data) {
161     printf("Warning: element with specified key does not exist (%s)\n", key);
162     return 0;
163   }
164
165   return data->mean;
166 }
167
168 /* Injecting random value from the histogram */
169 static inline double xbt_hist_time(char *key)
170 {
171   xbt_dict_t mydict = get_dict();
172   xbt_hist_t* data  = xbt_dict_get_or_null(mydict, key);
173
174   if (!data) {
175     printf("Warning: element with specified key does not exist (%s)\n", key);
176     return 0;
177   }
178
179   /* Choosing random interval of the histogram */
180   RngStream rng_stream = get_randgen();
181   double r             = RngStream_RandU01(rng_stream);
182   int k                = 0;
183   double left          = 0;
184   double right         = 1;
185   for (int i = 0; i < (data->n - 1); i++) {
186     left += (i == 0) ? 0 : data->percentage[i - 1];
187     right += data->percentage[i];
188     if (left < r && r <= right)
189       k = i;
190   }
191
192   /* Choosing random value inside the interval of the histogram */
193   double r2    = RngStream_RandU01(rng_stream);
194   double timer = data->breaks[k] + r2 * (data->breaks[k + 1] - data->breaks[k]);
195
196   return timer;
197 }
198
199 #endif // __INJECT_H__
200