code wiki / _hdl_build / nx_eqsat_congruence_bench.nx

nx_eqsat_congruence_bench.nx

buildroot/runtime/_hdl_build/nx_eqsat_congruence_bench.nx

9051 B167 linesdepth 7pulls 9 transitivereach 0 importersview sourcekind benchtopic eqsat
docsdependenciesstructsconstsfunctions

about

nx_eqsat_congruence_bench.nx -- NON-TOY CONGRUENCE-HEAVY race vs egg 0.11.0. THE RACE (engine-only, SAME expression both sides): egg target = /tmp/race_egg/examples/nx_cong.rs, the congruence-heavy graph: base a = (* x 8), b = (<< x 3) -- mul-pow2 merges a~b N pairs la_i = (- a c_i), lb_i = (- b c_i) -- become CONGRUENT after a~b root = (+ (+ ... (+ 0 (+ la_0 lb_0)) ...) (+ la_{N-1} lb_{N-1})) so after the single base merge, the engine's congruence closure must propagate N parent merges (la_i ~ lb_i) -- the exact reachability work egg's deferred rebuild does and the pre-MEET nx_eqsat could NOT do. This is NOT the toy (* x 8) single-rewrite race; congruence FIRES N times per iteration. OUR side, per timed iteration (the SAME end-to-end optimize pipeline egg ran, no proxy, no membership/provenance machinery egg lacks): nx_eqsat_init (fresh e-graph) enable_meet (egg hashcons + congruence rebuild ON) build a, b, N parent pairs, root (egg's RecExpr build) nx_eqsat_saturate (egg's Runner::run -- rules + rebuild to fixpoint) nx_eqsat_recompute_best (egg's Extractor bottom-up cost) nx_eqsat_extract_best_node(root) (egg's find_best) FAIL LOUD: before timing, one verified iteration asserts congruence actually fired -- find(la_i)==find(lb_i) for ALL i (== egg's internal congruence). A fast wrong answer (congruence NOT propagated) loses, exit nonzero. Output (one line): NX_CONG_ENGINE_ONLY N=<n> ITERS=<it> CONG_MERGES=<n> TOTAL_US=<t> US_PER_OP_NS=<u> (US_PER_OP_NS = total_us*1000/iters = nanoseconds/op; divide by 1000 for us/op.) SOVEREIGN: no .sh; runs on the pinned NishiLang compiler. license_tier: ORIGINAL

dependencies 1 imports · 0 importers

nx_eqsat.nx nx_eqsat_congruence_bench.nx

imports: nx_eqsat.nx

imported by: nobody (leaf or entry point)

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main _one_iter nx_eqsat_init nx_eqsat_enable_meet nx_eqsat_add_var nx_eqsat_add nx_eqsat_op_is_valid nx_eqsat_arity_for nx_cf_intern_const nx_eqsat_add_const nx_eqsat_add ↻ nx_eqsat_mix nx_cf_make_const_node nx_eqsat_new_class nx_eqsat_find nx_eqsat_find ↻ nx_eqsat_fold_value nx_eqsat_op_to_gate_kind nx_gsim_kind_supported nx_eqsat_arity_for ↻ nx_eqsat_find ↻ nx_gsim_eval_cell nx_eqsat_op_cost nx_eqsat_new_class ↻ nx_eqsat_union_cited nx_eqsat_find ↻ nx_eqsat_log_rule nx_eqsat_push_dirty nx_eqsat_fingerprint nx_eqsat_mix ↻ nx_hmap_has nx_hmap_probe_find nx_hmap_hash nx_hmap_entry_at nx_hmap_get nx_hmap_probe_find ↻ nx_hmap_entry_at ↻ nx_eqsat_node_matches nx_eqsat_arity_for ↻ nx_eqsat_find ↻

structs

none

consts

33const K_MAGIC_2000: i64 = 2000
34const K_MAGIC_2048: i64 = 2048
35const K_MAGIC_4096: i64 = 4096
36const K_MAGIC_8192: i64 = 8192

functions

38func _emit_num(v: i64) -> i64
called by 1: main
46func _emit_str(s: *u8, len: i64) -> i64 { sys_write(1, s, len); return 0 }
called by 1: main
47func _nl() -> i64 { let z: *u8 = sys_mmap(2); z[0] = 10; sys_write(1, z, 1); return 0 }
called by 1: main
54func _one_iter(g: *NxEGraph,
108func main() -> i64