From 00bbdacd9a1279ab6a85825a9102945840bebef2 Mon Sep 17 00:00:00 2001 From: Lucas Randazzo Date: Thu, 5 Sep 2024 17:19:07 +0200 Subject: [PATCH 1/4] Snoop: add verbose option to Michelson generation Prints out the generated michelson term --- .../lib_benchmarks_proto/michelson_commands.ml | 14 +++++++++++--- .../lib_benchmarks_proto/michelson_generation.ml | 12 ++++++++---- .../lib_benchmarks_proto/michelson_generation.mli | 10 ++++++++-- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/proto_alpha/lib_benchmarks_proto/michelson_commands.ml b/src/proto_alpha/lib_benchmarks_proto/michelson_commands.ml index b53daf1b8e5b..f1b9bdc11819 100644 --- a/src/proto_alpha/lib_benchmarks_proto/michelson_commands.ml +++ b/src/proto_alpha/lib_benchmarks_proto/michelson_commands.ml @@ -74,8 +74,8 @@ module Michelson_gen_cmd = struct let lift_opt f opt_arg state = match opt_arg with None -> state | Some arg -> f arg state - let handler (min_size, max_size, burn_in, seed) terms_count terms_kind - filename () = + let handler (min_size, max_size, burn_in, seed, verbose) terms_count + terms_kind filename () = let open Lwt_result_syntax in let default = Michelson_generation.default_generator_config in let min = Option.value ~default:default.target_size.min min_size in @@ -189,7 +189,15 @@ module Michelson_gen_cmd = struct in Tezos_clic.arg ~doc:"RNG seed" ~long:"seed" ~placeholder:"int" seed - let options = Tezos_clic.args4 min_size_arg max_size_arg burn_in_arg seed_arg + let verbose_arg = + Tezos_clic.switch + ~doc:"Print the generated terms in the standard output" + ~long:"verbose" + ~short:'v' + () + + let options = + Tezos_clic.args5 min_size_arg max_size_arg burn_in_arg seed_arg verbose_arg let params = Tezos_clic.( diff --git a/src/proto_alpha/lib_benchmarks_proto/michelson_generation.ml b/src/proto_alpha/lib_benchmarks_proto/michelson_generation.ml index d1422930010a..d90050c07c8d 100644 --- a/src/proto_alpha/lib_benchmarks_proto/michelson_generation.ml +++ b/src/proto_alpha/lib_benchmarks_proto/michelson_generation.ml @@ -72,7 +72,7 @@ module Michelson_base_samplers = Samplers.Michelson_base (* ----------------------------------------------------------------------- *) -let make_data_sampler rng_state config = +let make_data_sampler ?(verbose = false) rng_state config = let target_size = Base_samplers.sample_in_interval rng_state ~range:config.target_size in @@ -90,9 +90,11 @@ let make_data_sampler rng_state config = in let burn_in = target_size * config.burn_in_multiplier in let generator = Data.generator ~burn_in rng_state in - generator rng_state + let r = generator rng_state in + if verbose then Format.printf "%a@." Michelson_v1_printer.print_expr r.term ; + r -let make_code_sampler rng_state config = +let make_code_sampler ?(verbose = false) rng_state config = let target_size = Base_samplers.sample_in_interval rng_state ~range:config.target_size in @@ -110,4 +112,6 @@ let make_code_sampler rng_state config = in let burn_in = target_size * config.burn_in_multiplier in let generator = Code.generator ~burn_in rng_state in - generator rng_state + let r = generator rng_state in + if verbose then Format.printf "%a@." Michelson_v1_printer.print_expr r.term ; + r diff --git a/src/proto_alpha/lib_benchmarks_proto/michelson_generation.mli b/src/proto_alpha/lib_benchmarks_proto/michelson_generation.mli index 89868e6f58b1..061dadb972b1 100644 --- a/src/proto_alpha/lib_benchmarks_proto/michelson_generation.mli +++ b/src/proto_alpha/lib_benchmarks_proto/michelson_generation.mli @@ -49,12 +49,18 @@ val generator_config_encoding : generator_config Data_encoding.t (** [make_data_sampler] constructs a Michelson data sampler based on the infrastructure available in {!Tezos_benchmark_alpha.Michelson_mcmc_samplers}. *) val make_data_sampler : - Random.State.t -> generator_config -> Michelson_mcmc_samplers.michelson_data + ?verbose:bool -> + Random.State.t -> + generator_config -> + Michelson_mcmc_samplers.michelson_data (** [make_code_sampler] constructs a Michelson code sampler based on the infrastructure available in {!Tezos_benchmark_alpha.Michelson_mcmc_samplers}. *) val make_code_sampler : - Random.State.t -> generator_config -> Michelson_mcmc_samplers.michelson_code + ?verbose:bool -> + Random.State.t -> + generator_config -> + Michelson_mcmc_samplers.michelson_code (** [Samplers] is an instance of the direct-style (non-MCMC based) samplers implemented in {!Tezos_benchmark_alpha.Michelson_samplers}. *) -- GitLab From 0ed2322819e10d085fcf4112686129d06c06916c Mon Sep 17 00:00:00 2001 From: Lucas Randazzo Date: Thu, 5 Sep 2024 17:19:53 +0200 Subject: [PATCH 2/4] Snoop: add an `append` function for Michelson generation --- src/proto_alpha/lib_benchmark/michelson_mcmc_samplers.ml | 7 +++++++ src/proto_alpha/lib_benchmark/michelson_mcmc_samplers.mli | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/src/proto_alpha/lib_benchmark/michelson_mcmc_samplers.ml b/src/proto_alpha/lib_benchmark/michelson_mcmc_samplers.ml index 0515479b29f6..99f4d9c22408 100644 --- a/src/proto_alpha/lib_benchmark/michelson_mcmc_samplers.ml +++ b/src/proto_alpha/lib_benchmark/michelson_mcmc_samplers.ml @@ -102,6 +102,13 @@ let load ~filename = err ; exit 1 +let append ~filename ~terms = + if not (Sys.file_exists filename) then save ~filename ~terms + else + let previous_terms = load ~filename in + let all_terms = previous_terms @ terms in + save ~filename ~terms:all_terms + (* Helpers *) let base_type_to_michelson_type (typ : Type.Base.t) = diff --git a/src/proto_alpha/lib_benchmark/michelson_mcmc_samplers.mli b/src/proto_alpha/lib_benchmark/michelson_mcmc_samplers.mli index bd67d13e3c16..5a4f27978ec9 100644 --- a/src/proto_alpha/lib_benchmark/michelson_mcmc_samplers.mli +++ b/src/proto_alpha/lib_benchmark/michelson_mcmc_samplers.mli @@ -60,6 +60,11 @@ val save : filename:string -> terms:michelson_sample list -> unit Exits with code 1 if an error arises during decoding or file manipulation. *) val load : filename:string -> michelson_sample list +(** Appends a list of samples to a file. + Creates the file if non-existent. + Exits with code 1 if an error arises during encoding or file manipulation. *) +val append : filename:string -> terms:michelson_sample list -> unit + (** [Make_code_sampler] produces a sampler for well-typed Michelson code. The parameters of the functor are: - a module [Michelson_base] implementing samplers for basic values -- GitLab From 5e3f0f52425459bef3e01430afc84ea6a132df21 Mon Sep 17 00:00:00 2001 From: Lucas Randazzo Date: Thu, 5 Sep 2024 17:21:58 +0200 Subject: [PATCH 3/4] Snoop: iterative michelson generation Might help the GC, because we don't have to keep a list of `n` generators, which could point to old values used during the burn-in --- .../michelson_commands.ml | 36 ++++++++++--------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/src/proto_alpha/lib_benchmarks_proto/michelson_commands.ml b/src/proto_alpha/lib_benchmarks_proto/michelson_commands.ml index f1b9bdc11819..c1cadff16e60 100644 --- a/src/proto_alpha/lib_benchmarks_proto/michelson_commands.ml +++ b/src/proto_alpha/lib_benchmarks_proto/michelson_commands.ml @@ -83,6 +83,9 @@ module Michelson_gen_cmd = struct let burn_in_multiplier = Option.value ~default:default.burn_in_multiplier burn_in in + if Sys.file_exists filename then ( + Format.eprintf "File %s already exists, exiting@." filename ; + exit 1) ; let rng_state = match seed with | None -> @@ -114,23 +117,22 @@ module Michelson_gen_cmd = struct terms_count "Generating term" in - let terms = - match terms_kind with - | "data" -> - Stdlib.List.init terms_count (fun _i -> - progress () ; - Michelson_mcmc_samplers.Data - (Michelson_generation.make_data_sampler rng_state cfg)) - | "code" -> - Stdlib.List.init terms_count (fun _i -> - progress () ; - Michelson_mcmc_samplers.Code - (Michelson_generation.make_code_sampler rng_state cfg)) - | _ -> - Format.eprintf "Term kind must be either \"data\" or \"code\"@." ; - exit 1 - in - Michelson_mcmc_samplers.save ~filename ~terms ; + for _ = 1 to terms_count do + progress () ; + let s = + match terms_kind with + | "data" -> + Michelson_mcmc_samplers.Data + (Michelson_generation.make_data_sampler ~verbose rng_state cfg) + | "code" -> + Michelson_mcmc_samplers.Code + (Michelson_generation.make_code_sampler ~verbose rng_state cfg) + | _ -> + Format.eprintf "Term kind must be either \"data\" or \"code\"@." ; + exit 1 + in + Michelson_mcmc_samplers.append ~filename ~terms:[s] + done ; return_unit let min_size_arg = -- GitLab From da6f733133f4ce1468ea06ff3de363a22897cc97 Mon Sep 17 00:00:00 2001 From: Lucas Randazzo Date: Thu, 5 Sep 2024 17:24:08 +0200 Subject: [PATCH 4/4] Snoop: clear Hash consing tables after each generated Michelson term The actual fix. Doesn't impact performance too much, probably because each term is brand new, so the sets of hash consigned terms between two full terms have very little overlap. Most of the performance gains are during the burn-ins. --- .../lib_benchmark/lib_benchmark_type_inference/type.ml | 5 +++++ .../lib_benchmark/lib_benchmark_type_inference/type.mli | 3 +++ src/proto_alpha/lib_benchmarks_proto/michelson_commands.ml | 3 ++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/proto_alpha/lib_benchmark/lib_benchmark_type_inference/type.ml b/src/proto_alpha/lib_benchmark/lib_benchmark_type_inference/type.ml index bc8d164c6c5c..31427fac44fb 100644 --- a/src/proto_alpha/lib_benchmark/lib_benchmark_type_inference/type.ml +++ b/src/proto_alpha/lib_benchmark/lib_benchmark_type_inference/type.ml @@ -198,3 +198,8 @@ let empty = Stack.Table.hashcons Stack.table Empty_t let stack_var x = Stack.Table.hashcons Stack.table (Stack_var_t x) let item head tail = Stack.Table.hashcons Stack.table (Item_t (head, tail)) + +(* Clear tables *) +let clear_tables () = + Base.(Table.clear table) ; + Stack.(Table.clear table) diff --git a/src/proto_alpha/lib_benchmark/lib_benchmark_type_inference/type.mli b/src/proto_alpha/lib_benchmark/lib_benchmark_type_inference/type.mli index bdc806590b25..c9e690929ce9 100644 --- a/src/proto_alpha/lib_benchmark/lib_benchmark_type_inference/type.mli +++ b/src/proto_alpha/lib_benchmark/lib_benchmark_type_inference/type.mli @@ -109,3 +109,6 @@ val empty : Stack.t val stack_var : int -> Stack.t val item : Base.t -> Stack.t -> Stack.t + +(** Clears the hash consing tables to free memory *) +val clear_tables : unit -> unit diff --git a/src/proto_alpha/lib_benchmarks_proto/michelson_commands.ml b/src/proto_alpha/lib_benchmarks_proto/michelson_commands.ml index c1cadff16e60..9b5523274a60 100644 --- a/src/proto_alpha/lib_benchmarks_proto/michelson_commands.ml +++ b/src/proto_alpha/lib_benchmarks_proto/michelson_commands.ml @@ -131,7 +131,8 @@ module Michelson_gen_cmd = struct Format.eprintf "Term kind must be either \"data\" or \"code\"@." ; exit 1 in - Michelson_mcmc_samplers.append ~filename ~terms:[s] + Michelson_mcmc_samplers.append ~filename ~terms:[s] ; + Type.clear_tables () done ; return_unit -- GitLab