Source file registration.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
module Name_table = Namespace.Hashtbl
exception Benchmark_not_found of Namespace.t
exception Model_not_found of Namespace.t
exception Local_model_not_found of String.t
exception Parameter_not_found of Free_variable.t
type benchmark_info = Benchmark.t
type model_info = {
model : Model.packed_model;
from : local_model_info list;
codegen_destination : string option;
}
and local_model_info = {bench_name : Namespace.t; local_model_name : string}
type parameter_info = Namespace.t list
type local_model_benchmark_names = Namespace.Set.t
let bench_table : benchmark_info Name_table.t = Name_table.create 51
let model_table : model_info Name_table.t = Name_table.create 51
let local_model_table : local_model_benchmark_names String.Hashtbl.t =
String.Hashtbl.create 51
let parameter_table : parameter_info Name_table.t = Name_table.create 51
let clic_table : unit Tezos_clic.command list ref = ref []
let register_parameter model_name (param : Free_variable.t) =
let ns = Free_variable.to_namespace param in
match Name_table.find_opt parameter_table ns with
| None -> Name_table.add parameter_table ns [model_name]
| Some l -> Name_table.replace parameter_table ns (model_name :: l)
let register_param_from_model (model : Model.packed_model) =
match model with
| Model model ->
let module M = (val model) in
let fv_set = Model.get_free_variable_set model in
Free_variable.Set.iter (register_parameter M.name) fv_set
let fix_codegen_destination destination =
if String.contains destination '/' then destination
else
Filename.concat "src/proto_alpha/lib_protocol"
@@ destination ^ "_costs_generated.ml"
let register_model (type a) ?codegen_destination bench_name local_model_name
(model : a Model.t) : unit =
let codegen_destination =
Option.map fix_codegen_destination codegen_destination
in
let register_local_model bench_name local_model_name : unit =
match String.Hashtbl.find_opt local_model_table local_model_name with
| None ->
String.Hashtbl.add
local_model_table
local_model_name
(Namespace.Set.singleton bench_name)
| Some bench_names ->
String.Hashtbl.replace
local_model_table
local_model_name
(Namespace.Set.add bench_name bench_names)
in
let register_packed_model = function
| Model.Model m as model -> (
let module M = (val m) in
let name = M.name in
match Name_table.find_opt model_table name with
| None ->
register_param_from_model model ;
register_local_model bench_name local_model_name ;
Name_table.add
model_table
name
{
model;
from = [{bench_name; local_model_name}];
codegen_destination;
}
| Some {model = Model m'; from; _} ->
if
not
(Free_variable.Set.equal
(Model.get_free_variable_set m)
(Model.get_free_variable_set m'))
then
Format.eprintf
"Warning: Registered different model with same name %a@."
Namespace.pp
name ;
Name_table.replace
model_table
name
{
model;
from = {bench_name; local_model_name} :: from;
codegen_destination;
})
in
match model with
| Aggregate {sub_models; _} -> List.iter register_packed_model sub_models
| Abstract {model; _} -> register_packed_model (Model.Model model)
let register_model_for_code_generation ?destination local_model_name model =
register_model
?codegen_destination:destination
(Namespace.of_string "no_benchmark")
local_model_name
model
let register ?(add_timer = true) ((module Bench) : Benchmark.t) =
if Name_table.mem bench_table Bench.name then (
Format.eprintf
"Benchmark %a already registered! exiting@."
Namespace.pp
Bench.name ;
exit 1)
else () ;
let ((module Bench) : Benchmark.t) =
if add_timer then
let module Bench = struct
include Bench
let models =
List.map
(fun (s, m) ->
( s,
Model.(
add_model m Builtin_models.timer_model
|> precompose (fun w -> (w, ()))) ))
models
end in
(module Bench)
else (module Bench)
in
let module Bench = struct
include Bench
let purpose =
match purpose with
| Other_purpose _ -> purpose
| Generate_code destination ->
let destination = fix_codegen_destination destination in
Generate_code destination
end in
List.iter
(fun (local_model_name, m) -> register_model Bench.name local_model_name m)
Bench.models ;
Name_table.add bench_table Bench.name (module Bench)
let register_simple ?add_timer (bench : Benchmark.simple) =
register
?add_timer
(module struct
include (val bench)
let models =
[
( (match group with
| Generic -> "*"
| Group g -> g
| Standalone -> Namespace.(cons name "model" |> to_string)),
model );
]
let create_benchmarks ~rng_state ~bench_num config =
List.repeat bench_num (fun () -> create_benchmark ~rng_state config)
end)
let register_simple_with_num ?add_timer (bench : Benchmark.simple_with_num) =
register
?add_timer
(module struct
include (val bench)
let models =
[
( (match group with
| Generic -> "*"
| Group g -> g
| Standalone -> Namespace.(cons name "model" |> to_string)),
model );
]
end)
let add_command cmd = clic_table := cmd :: !clic_table
let all_benchmarks () : (Namespace.t * benchmark_info) list =
Name_table.to_seq bench_table
|> List.of_seq
|> List.sort (fun (b1, _) (b2, _) -> Namespace.compare b1 b2)
let all_tags () : string list =
Name_table.to_seq bench_table
|> Seq.map snd |> List.of_seq
|> List.map (fun b -> Benchmark.tags b)
|> List.flatten
|> List.sort_uniq (fun t1 t2 -> String.compare t1 t2)
let all_models () =
Name_table.to_seq model_table
|> List.of_seq
|> List.sort (fun (s, _) (s', _) -> Namespace.compare s s')
let all_model_names () = all_models () |> List.map fst
let all_parameters () =
Name_table.to_seq parameter_table
|> List.of_seq
|> List.sort (fun (p1, _) (p2, _) -> Namespace.compare p1 p2)
|> List.map (fun (a, b) -> (Free_variable.of_namespace a, b))
let all_local_model_names () =
String.Hashtbl.to_seq_keys local_model_table
|> List.of_seq
|> List.filter (fun s -> not (String.equal s "*"))
|> List.sort_uniq String.compare
let all_custom_commands () = !clic_table
let find_benchmarks_with_tags ~mode tag_list =
let filter =
match mode with
| `All ->
fun (_, b) ->
List.for_all
(fun tag -> List.mem ~equal:String.equal tag (Benchmark.tags b))
tag_list
| `Exact ->
fun (_, b) ->
let benchmark_tags = List.sort String.compare (Benchmark.tags b) in
List.equal
String.equal
(List.sort String.compare tag_list)
benchmark_tags
| `Any ->
fun (_, b) ->
List.exists
(fun tag -> List.mem ~equal:String.equal tag (Benchmark.tags b))
tag_list
in
Name_table.to_seq bench_table
|> List.of_seq |> List.filter filter
|> List.sort (fun (b1, _) (b2, _) -> Namespace.compare b1 b2)
let find_in_namespace table pattern =
Name_table.fold
(fun name e acc ->
if Namespace.name_match pattern name then (name, e) :: acc else acc)
table
[]
let find_benchmark name = Name_table.find bench_table name
let find_benchmark_exn name =
match find_benchmark name with
| None ->
Format.eprintf "No benchmark named %a found.@." Namespace.pp name ;
raise (Benchmark_not_found name)
| Some b -> b
let find_benchmarks_in_namespace = find_in_namespace bench_table
let find_model name = Name_table.find model_table name
let find_model_exn name =
match find_model name with
| None ->
Format.eprintf "No model named %a found.@." Namespace.pp name ;
raise (Model_not_found name)
| Some m -> m
let find_local_model name =
String.Hashtbl.find local_model_table name
|> Option.map (fun benches -> Namespace.Set.to_seq benches |> List.of_seq)
let find_local_model_exn name =
match find_local_model name with
| None ->
Format.eprintf
"No local model named %a found.@."
Format.pp_print_string
name ;
raise (Local_model_not_found name)
| Some m -> m
let find_models_in_namespace = find_in_namespace model_table
let find_parameter name =
let name = Free_variable.to_namespace name in
Name_table.find parameter_table name
let find_parameter_exn name =
match find_parameter name with
| None ->
Format.eprintf "No parameter %a found.@." Free_variable.pp name ;
raise (Parameter_not_found name)
| Some m -> m
let find_parameters_in_namespace ns =
find_in_namespace parameter_table ns
|> List.map (fun (x, y) -> (Free_variable.of_namespace x, y))