let mem_stat () = let stat = Gc.stat() in let word = float_of_int (Sys.word_size / 8) in let free = float_of_int stat.Gc.free_words *. word /. 1024.0 in let total = float_of_int stat.Gc.heap_words *. word /. 1024.0 in let allocated = total -. free in let str = sprintf "allocated = %f (free = %f; total_size = %f; %f)\n" allocated free total (free /. total) in print_string str;; (* allocated = 85862 *) mem_stat();; Gc.set { (Gc.get()) with Gc.verbose = 0x05 };; Gc.compact();; (* allocated = 60243 *) mem_stat();; flyspeck_needs "../formal_lp/formal_interval/m_verifier.hl";; (* allocated = 129006 *) mem_stat();; Gc.compact();; (* allocated = 80510 *) mem_stat();; Arith_cache.print_stat();; Arith_float.print_stat();; let reset_all () = Arith_cache.reset_cache(); Arith_cache.reset_stat(); Arith_float.reset_cache(); Arith_float.reset_stat();; reset_all();; Gc.compact();; (* allocated = 79346 *) mem_stat();; (**************************) (* Examples *) let heart_poly = expr_to_vector_fun `-- x1 * x6 pow 3 + &3 * x1 * x6 * x7 pow 2 - x3 * x7 pow 3 + &3 * x3 * x7 * x6 pow 2 - x2 * x5 pow 3 + &3 * x2 * x5 * x8 pow 2 - x4 * x8 pow 3 + &3 * x4 * x8 * x5 pow 2 - #0.9563453`;; let poly1 = `x2 + x3 + x5 + x6 - #7.99 - #0.00385 * delta_y x1 x2 x3 x4 x5 x6 - #2.75 * ((x1 + x4) * #0.5 - sqrt (&8))`;; let poly_ineq = (expr_to_vector_fun o rand o concl o REWRITE_CONV[Sphere.delta_y; Sphere.delta_x]) poly1;; let heart_min = `-- #1.7435` and poly_min = `&0`;; let heart_dom = `[-- #0.1; #0.4; -- #0.7; -- #0.7; #0.1; -- #0.1; -- #0.3; -- #1.1]`, `[#0.4; &1; -- #0.4; #0.4; #0.2; #0.2; #1.1; -- #0.3]`;; let poly_dom = `[sqrt (&8); &2; &2; sqrt (&8); &2; &2]`, `[&3; #2.07; #2.07; &4 * #1.26; #2.07; #2.07]`;; (***********************************) let test_verify pp poly_tm min_flag val_tm (xx,zz) eps = let total_start = Sys.time() in let n = (get_dim o fst o dest_abs) poly_tm in let xx1 = convert_to_float_list pp true xx and zz1 = convert_to_float_list pp false zz in let xx_float = map float_of_float_tm (dest_list xx1) and zz_float = map float_of_float_tm (dest_list zz1) in let eval_fs, tf = mk_verification_functions pp poly_tm min_flag val_tm in let certificate = run_test tf xx_float zz_float false 0.0 true true true true eps in let c1 = transform_result xx_float zz_float certificate in let start = Sys.time() in let result = m_verify_list n pp eval_fs c1 xx1 zz1 in let finish = Sys.time() in let _ = report (sprintf "Total time: %f; Verification time: %f" (finish -. total_start) (finish -. start)) in result;; (******) (* PVS: 79.68; 26.14 8 (10): 27.937; 9.176 64 (6): 24.249; 5.672 512 (3): 23.113; 3.428 Why is the base 10 much faster than 8? Possible explanation: the domain is described by decimal numbers, so computations with the base 10 are faster in general (the approximation is better: requires less digits). 10 (10): 23.205; 4.376 10 (10, cached, float_cached): 20.001; 1.548 10 (10, float_cached): 19.769; 1.744 100 (5): 21.733; 3.180 100 (5, cached): 20.737; 2.196 *) reset_all();; test_verify 10 heart_poly true heart_min heart_dom 1e-10;; Arith_cache.print_stat();; Arith_float.print_stat();; (* 117589 *) mem_stat();; Gc.compact();; (* 80340 *) mem_stat();; reset_all();; Gc.compact();; (* 79372 *) mem_stat();; (* 8 (10): 215.953; 112.399 64 (6): 162.754; 62.588 64 (5): 150.573; 49.991 512 (3): 137.967; 32.250 10 (10): 185.211; 83.785 100 (5): 139.821; 40.975 100 (5, cached): 119.267; 20.009 *) reset_all ();; (* test_verify 5 poly_ineq true poly_min poly_dom 0.0;; Arith_cache.print_stat();; *) (******) let pp = 10;; let n = (get_dim o fst o dest_abs) poly_ineq;; let xx, zz = poly_dom;; let xx1 = convert_to_float_list pp true xx and zz1 = convert_to_float_list pp false zz;; let xx_float = map float_of_float_tm (dest_list xx1) and zz_float = map float_of_float_tm (dest_list zz1);; Arith_cache.print_stat();; Arith_float.print_stat();; let eval_fs, tf = mk_verification_functions pp poly_ineq true poly_min;; Arith_cache.print_stat();; Arith_float.print_stat();; let certificate = run_test tf xx_float zz_float false 0.0 true true true true 0.0;; let c1 = transform_result xx_float zz_float certificate;; reset_all();; (* 10 (10, cached): 30.589 *) (* 10 (10, cached, float_cached): 16.137 *) (* 10 (10, float_cached): 17.001 *) (* 100 (5, cached): 20.101 *) (* 100 (5, cached, float_cached): 10.452 *) let _ = let start = Sys.time() in let result = m_verify_list n pp eval_fs c1 xx1 zz1 in let finish = Sys.time() in let _ = report (sprintf "Verification time: %f" (finish -. start)) in result;; Arith_cache.print_stat();; Arith_float.print_stat();; Gc.compact();; (* 89346 *) mem_stat();; reset_all();; Gc.compact();; (* 79973 *) mem_stat();; (* num *) let add_list = !Arith_cache.add_list and mul_list = !Arith_cache.mul_list and sub_le_list = !Arith_cache.sub_le_list;; (* 10: 24.621 *) (* 100: 7.612 *) test 1 (map Arith_hash.raw_add_conv_hash) add_list;; (* 100: 22.681 *) test 1 (map Arith_hash.raw_mul_conv_hash) mul_list;; (* 100: 9.917 *) test 1 (map (fun tm1, tm2 -> Arith_hash.raw_sub_and_le_hash_conv tm1 tm2)) sub_le_list;; Arith_cache.reset_cache();; (* 10: 6.064 *) (* 100: 1.884 *) test 1 (map raw_add_conv_hash) add_list;; (* 100: 2.396 *) test 1 (map raw_mul_conv_hash) mul_list;; (* 100: 2.384 *) test 1 (map (fun tm1, tm2 -> raw_sub_and_le_hash_conv tm1 tm2)) sub_le_list;; (****************) (* float *) let mul_lo_list = !Arith_float.mul_lo_list and mul_hi_list = !Arith_float.mul_hi_list and add_lo_list = !Arith_float.add_lo_list and add_hi_list = !Arith_float.add_hi_list;; (* 10: 10.308 *) reset_all();; test 1 (map (fun p,tm1,tm2 -> float_mul_lo p tm1 tm2)) mul_lo_list;; (* 10: 13.152 *) reset_all();; test 1 (map (fun p,tm1,tm2 -> float_mul_hi p tm1 tm2)) mul_hi_list;; (* 10: 2.688 *) reset_all();; test 1 (map (fun p,tm1,tm2 -> float_add_lo p tm1 tm2)) add_lo_list;; (* 10: 3.104 *) reset_all();; test 1 (map (fun p,tm1,tm2 -> float_add_hi p tm1 tm2)) add_hi_list;; (***********) let float_hash tm = let s, n_tm, e_tm = dest_float tm in s ^ (num_tm_hash n_tm) ^ "e" ^ (num_tm_hash e_tm);; let float_op_hash pp tm1 tm2 = string_of_int pp ^ float_hash tm1 ^ "x" ^ float_hash tm2;; let float_mul_table = Hashtbl.create 10000;; let float_mul_lo_cached pp tm1 tm2 = let hash = float_op_hash pp tm1 tm2 in try Hashtbl.find float_mul_table hash with Not_found -> let result = float_mul_lo pp tm1 tm2 in let _ = Hashtbl.add float_mul_table hash result in result;; reset_all();; (* 10: 3.624 *) test 1 (map (fun p,tm1,tm2 -> float_mul_lo_cached p tm1 tm2)) mul_lo_list;; (* 2150 *) Hashtbl.length float_mul_table;; (* 24044 *) length mul_lo_list;; let x = 2;; (****************) Hashtbl.length Arith_cache.mul_table;; Hashtbl.length Arith_cache.sub_le_table;; Hashtbl.length Arith_cache.add_table;; (* 100: 0.148 *) test 1 (map Arith_hash.raw_suc_conv_hash) !Arith_cache.suc_list;; (* 100: 0.180 *) test 1 (map Arith_hash.raw_eq0_hash_conv) !Arith_cache.eq0_list;; (* 100: 0.532 *) test 1 (map Arith_hash.raw_div_hash_conv) !Arith_cache.div_list;; (* 100: 10.196 *) test 1 (map (fun tm1, tm2 -> Arith_hash.raw_sub_and_le_hash_conv tm1 tm2)) !Arith_cache.sub_le_list;; let mul_table = Hashtbl.create 100000;; let mul_cache1 tm = if Hashtbl.mem mul_table tm then Hashtbl.find mul_table tm else let result = Arith_hash.raw_mul_conv_hash tm in let _ = Hashtbl.add mul_table tm result in result;; (* 100: 25.882 *) Hashtbl.clear mul_table;; test 1 (map mul_cache1) !Arith_cache.mul_list;; (* 100: 44.398 *) test 1 (map mul_cache1) !Arith_cache.mul_list;; (* 100: 22.609 *) test 1 (map (Hashtbl.mem mul_table)) !Arith_cache.mul_list;; (* 100: 22.233 *) test 1 (map (Hashtbl.find mul_table)) !Arith_cache.mul_list;; (* 100: 0.044 *) test 1 (map Hashtbl.hash) !Arith_cache.mul_list;; let rec num_tm_hash tm = if is_comb tm then let b_tm, n_tm = dest_comb tm in let str = (fst o dest_const) b_tm in str ^ num_tm_hash n_tm else "";; let op_tm_hash tm = let lhs, tm2 = dest_comb tm in let tm1 = rand lhs in num_tm_hash tm1 ^ "x" ^ num_tm_hash tm2;; (* 0.340 *) test 1 (map op_tm_hash) !Arith_cache.mul_list;; (* 0.428 *) test 1 (map (Hashtbl.hash o op_tm_hash)) !Arith_cache.mul_list;; (******) let mul_table2 = Hashtbl.create 10000;; let add_table2 = Hashtbl.create 10000;; let div_table2 = Hashtbl.create 10000;; let mul_cache2 tm = let hash = op_tm_hash tm in try Hashtbl.find mul_table2 hash with Not_found -> let result = Arith_hash.raw_mul_conv_hash tm in let _ = Hashtbl.add mul_table2 hash result in result;; let add_cache2 tm = let hash = op_tm_hash tm in try Hashtbl.find add_table2 hash with Not_found -> let result = Arith_hash.raw_add_conv_hash tm in let _ = Hashtbl.add add_table2 hash result in result;; let div_cache2 tm = let hash = op_tm_hash tm in try Hashtbl.find div_table2 hash with Not_found -> let result = Arith_hash.raw_div_hash_conv tm in let _ = Hashtbl.add div_table2 hash result in result;; Hashtbl.clear div_table2;; (* 100: 0.016 *) test 1 (map div_cache2) !Arith_cache.div_list;; (* 12 *) Hashtbl.length div_table2;; (* 100: 0.016 *) test 1 (map div_cache2) !Arith_cache.div_list;; Hashtbl.clear mul_table2;; (* 100: 2.536 *) test 1 (map mul_cache2) !Arith_cache.mul_list;; (* 4687 *) Hashtbl.length mul_table2;; (* 100: 0.384 *) test 1 (map mul_cache2) !Arith_cache.mul_list;; Hashtbl.clear add_table2;; (* 100: 2.052 *) test 1 (map add_cache2) !Arith_cache.add_list;; (* 5184 *) Hashtbl.length add_table2;; (* 100: 1.548 *) test 1 (map add_cache2) !Arith_cache.add_list;; let op_sizes tm = let lhs, tm2 = dest_comb tm in let tm1 = rand lhs in let list1 = striplist dest_comb tm1 and list2 = striplist dest_comb tm2 in length list1, length list2;; let l0 = map op_sizes !Arith_cache.mul_list;; (* 172 *) length (List.filter (fun p -> fst p = 1) l0);; (* 514 *) length (List.filter (fun p -> fst p = 2) l0);; (* 345 *) length (List.filter (fun p -> fst p = 3) l0);; (* 6 *) length (List.filter (fun p -> fst p = 4) l0);; (* 106 *) length (List.filter (fun p -> fst p = 5) l0);; (* 2872 *) length (List.filter (fun p -> fst p = 6) l0);; (* 672 *) length (List.filter (fun p -> fst p = 7) l0);; (* 0 *) length (List.filter (fun p -> snd p = 1) l0);; (* 93 *) length (List.filter (fun p -> snd p = 2) l0);; (* 1 *) length (List.filter (fun p -> snd p = 3) l0);; (* 13 *) length (List.filter (fun p -> snd p = 4) l0);; (* 175 *) length (List.filter (fun p -> snd p = 5) l0);; (* 4187 *) length (List.filter (fun p -> snd p = 6) l0);; (* 218 *) length (List.filter (fun p -> snd p = 7) l0);;