From 698589d8e3f06ae149d8279a7be130e91e17e035 Mon Sep 17 00:00:00 2001 From: Thomas Koehler Date: Tue, 30 Jun 2026 10:28:32 +0200 Subject: [PATCH 01/23] small case study improvements --- case_studies/dot_product/README.md | 175 +++++++++++++++ case_studies/dot_product/dot.cpp | 1 - case_studies/dot_product/dot.ml | 203 +----------------- case_studies/dot_product/dot_exp.cpp | 2 +- case_studies/gpu/matmul/matmul.ml | 2 +- case_studies/matmul/.gitignore | 2 + case_studies/matmul/matmul_check.ml | 2 +- case_studies/matmul/matmul_models.cpp | 4 +- case_studies/matmul/matmul_models.ml | 8 +- case_studies/matmul/matmul_opt_gotoblas.cpp | 69 ++++++ case_studies/opencv/box_filter_rowsum.cpp | 2 - .../opencv/box_filter_rowsum_models.cpp | 2 - .../opencv/box_filter_rowsum_models.ml | 14 +- lib/transfo/arith.ml | 2 +- lib/transfo/reduce_models.ml | 2 +- lib/transfo/rewrite.ml | 5 +- 16 files changed, 264 insertions(+), 231 deletions(-) create mode 100644 case_studies/dot_product/README.md create mode 100644 case_studies/matmul/matmul_opt_gotoblas.cpp diff --git a/case_studies/dot_product/README.md b/case_studies/dot_product/README.md new file mode 100644 index 000000000..9936cba6b --- /dev/null +++ b/case_studies/dot_product/README.md @@ -0,0 +1,175 @@ +============================HIGH LEVEL VIEW OF THE SCRIPT ============== + +s = 0 +__ghost(0 = reduce(0,0,f) à réécrire dans s ~> 0 pour avoir s ~> reduce(0,0,..)) +for i + __invariant "s ~> reduce(0,i,...)" + s += a[i] * b[i] + __ghost(reduce(0,i,f) + f(i) = reduce(0,i+1,f) à réécrire dans le contenu de s) + +--- unfold infix ops + +s = 0 +for i + __invariant "s ~> reduce(0,i,...)" + s = s + a[i] * b[i] + +--- tile +const int NB_BLOCK = a.length/B // to insert! with check divisibility? +s = 0 +for b = 0 to NB_BLOCK + __invariant "s ~> reduce(0,b*B,...)" + for i = b*B to (b+1)*B + __invariant "s ~> reduce(0,i,...)" + s = s + a[i] * b[i] + __ghost(reduce(0,i,f) + f(i) = reduce(0,i+1,f) à réécrire dans le contenu de s) + +--- local name + +s = 0 +for b + __invariant "s ~> reduce(0,b*B,...)" + t = s + // ghost(hide_cell, consume s~>v, produces "hidden(s,t)") + for i = b*B to (b+1)*B + __invariant "t ~> reduce(0,i,...)" + t = t + a[i] * b[i] + __ghost(reduce(0,i,f) + f(i) = reduce(0,i+1,f) à réécrire dans le contenu de t) + s = t + // ghost(hide_rev_cell, consume hidden(s,t), consume(t->w), produces "s~>w") + +--- insert def 'p' for the contents of 's' + +s = 0 +for b + __invariant "s ~> reduce(0,b*B,...)" + const int p = s; // sum of the prefix upto the block b + // in ctx, we have an alias: "p := reduce(0,b*B,...)" + t = s + for i = b*B to (b+1)*B + __invariant "t ~> reduce(0,i,...)" + t = t + a[i] * b[i] + __ghost(reduce(0,i,f) + f(i) = reduce(0,i+1,f) à réécrire dans le contenu de t) + s = t + +--- shift_var t by p + +s = 0 +for b + __invariant "s ~> reduce(0,b*B,...)" + const int p = s + // in ctx, we have an alias: "p := reduce(0,b*B,...)" + t = s - p // -p on write into t + for i = b*B to (b+1)*B + __invariant "t ~> reduce(0,i,...) - p" // -p on models of t + t = ((t + p) + a[i] * b[i]) - p // +p on reads on t, -p on write into t + // ICI problème: on avait + // __ghost(reduce(0,i,f) + f(i) = reduce(0,i+1,f) à réécrire dans le contenu de t) + // et maintenant il faut + // __ghost(reduce(0,i,f) - p + p + f(i) - p = reduce(0,i+1,f) - p à réécrire dans le contenu de t) + // ça je sais pas trop comment on va gérer... peut être sans typer les étapes intermédiaires ? + // parce que après on retrouve un moment où la ghost d'origine fonctionne telle quelle + s = t + p // +p on reads on t + + +--- unfold def of 'p' in the code (not in formulae), using the fact that s is not modified in the scope + +s = 0 +for b + __invariant "s ~> reduce(0,b*B,...)" + const int p = s + // in ctx, we have an alias: "p := reduce(0,b*B,...)" + t = s - s + // in ctx, we have t ~> reduce(0,b*B,...) - reduce(0,b*B,...) + for i = b*B to (b+1)*B + __invariant "t ~> reduce(0,i,...) - p" + t = ((t + s) + a[i] * b[i]) - s + // ... ici la ghost qui va bien + s = t + s + +-- remove s from the block-processing by arith_simpl + +s = 0 +for b + __invariant "s ~> reduce(0,b*B,...)" + const int p = s + // in ctx, we have an alias: "p := reduce(0,b*B,...)" + t = 0 + // HERE: need to insert a ghost rewriting "0" into "reduce(0,b*B,...) - reduce(0,b*B,...)" in contents of t + for i = b*B to (b+1)*B + __invariant "t ~> reduce(0,i,...) - p" + t = t + a[i] * b[i] + // la ghost d'accumulation fonctionne de nouveau ! + __ghost(reduce(0,i,f) + f(i) = reduce(0,i+1,f) à réécrire dans le contenu de t) + s = t + s + +--- optional step: turn "p" into ghost def; +-- alternative: inline "p", replacing it with "reduce(0,b*B,...)" in the formulae +-- if we do nothing, it's fine too, but we'll need to duplicate "const int p = s" + when we do the fusion step later. + +s = 0 +for b + __invariant "s ~> reduce(0,b*B,...)" + // BEFORE: + // const int p = s // where p is not used in the code, only in formulae + // in ctx, we have an alias: "p := reduce(0,b*B,...)" + // AFTER: + // __DEF(p, "reduce(0,b*B,...)"); + ... + + ==> in fine, I think inlining 'p' into 'reduce(0,b*B,...)' in formulae would be easiest. + + +--- hoist de t + +s = 0 +alloc t as an array of NB_BLOCK +for b + __xmodifies "t ~> UninitCell" // pas de spécification du modèle d'entrée ou de sortie + __invariant "s ~> reduce(0,b*B,...)" + t[b] = 0 + // ghost rewriting "0" into "reduce(0,b*B,...) - reduce(0,b*B,...)" in contents of t + for i = b*B to (b+1)*B + __invariant "t[b] ~> reduce(0,i,...) - reduce(0,b*B,...)" // MODIFIED CONTRACT: t becomes t[b] + t[b] = t[b] + a[i] * b[i] + __ghost(reduce(0,i,f) + f(i) = reduce(0,i+1,f) à réécrire dans le contenu de t) + // NOTE: at this point, the ctx stores t[b] ~> reduce(0,i,...) - reduce(0,b*B,...) + // the value of t[b] determines the contract for the fission that comes next + s = t[b] + s + + +--- fission + parallelization + +s = 0 +alloc t as an array of NB_BLOCK +parallel for b + __xmodifies "t[b] ~> t[b] ~> reduce(0,i,...) - reduce(0,b*B,...)" // NEW CONTRACT! + __DEF(p, "reduce(0,b*B,...)"); + t[b] = 0 + // ghost rewriting "0" into "reduce(0,b*B,...) - reduce(0,b*B,...)" in contents of t + for i = b*B to (b+1)*B + __invariant "t ~> reduce(0,i,...) - reduce(0,b*B,...)" + t[b] = t[b] + a[i] * b[i] + __ghost(reduce(0,i,f) + f(i) = reduce(0,i+1,f) à réécrire dans le contenu de t) +for b + // MOVED: contract on 's' is just moved here + __invariant "s ~> reduce(0,b*B,...)" + s = t[b] + s + + +--- cleanup, with infix ops + +s = 0 +alloc t as an array of NB_BLOCK +parallel for b + t[b] = 0 + for i = b*B to (b+1)*B + t[b] += a[i] * b[i] +for b + s += t[b] + + +===================== +# remark: it seems that we never need to exploit + "reduce(0,i,f) - reduce(0,j,f) = reduce(j,i,f)" diff --git a/case_studies/dot_product/dot.cpp b/case_studies/dot_product/dot.cpp index 2d73fa031..ca44b1549 100644 --- a/case_studies/dot_product/dot.cpp +++ b/case_studies/dot_product/dot.cpp @@ -3,7 +3,6 @@ __DECL(reduce_sum, "int * (int -> float) -> float"); __AXIOM(reduce_sum_empty, "forall (f: int -> float) -> 0.f =. reduce_sum(0, f)"); __AXIOM(reduce_sum_add_right, "forall (n: int) (f: int -> float) (_: n >= 0) -> reduce_sum(n, f) +. f(n) =. reduce_sum(n + 1, f)"); -__DEF(matmul, "fun (A B: int * int -> float) (p: int) -> fun (i j: int) -> reduce_sum(p, fun k -> A(i, k) *. B(k, j))"); /* Multiplies the vect A (dim n) by the vector B (dim n), * and returns the result of the scalar product. diff --git a/case_studies/dot_product/dot.ml b/case_studies/dot_product/dot.ml index 2f0564085..610fe0bea 100644 --- a/case_studies/dot_product/dot.ml +++ b/case_studies/dot_product/dot.ml @@ -2,20 +2,15 @@ open Optitrust open Prelude let _ = Flags.check_validity := true (* FIXME: false *) -let _ = Flags.use_resources_with_models := true let _ = Flags.preserve_specs_only := true let _ = Flags.pretty_matrix_notation := false let _ = Flags.recompute_resources_between_steps := true let _ = Flags.disable_stringreprs := true let _ = Flags.save_ast_for_steps := Some Flags.Steps_all (*Steps_important*) -(* let _ = Flags.save_ast_for_steps := Some Steps_all *) let int = trm_int -let part = 1 (* Choose which part you want to work on. *) - -(* Part 0: *) -let _ = if part = 1 then Run.script_cpp (fun () -> +let _ = Run.script_cpp (fun () -> (* !! Function.elim_infix_ops ~indepth:true []; *) !! Loop.tile (int 32) ~index:"bi" ~bound:TileDivides [cFor "i"]; @@ -29,27 +24,10 @@ let _ = if part = 1 then Run.script_cpp (fun () -> (* DEPRECATED? !! Sequence_basic.insert (trm_let (new_var "d", typ_f32) (trm_get (trm_find_var "s" []))) [tFirst; cForBody "bi"]; *) !! ( Variable.insert ~name:"d" ~typ:typ_f32 ~value:(trm_get (trm_find_var "s" [])) [cForBody "bi"; tFirst]; - - (* at this line, the output is the equivalent of dot0_gen.cpp, - beware that "==" needs to be replaced with "=." and all the "__is_true" must be removed; - some +. and + need to be fixed - ----> LATER: tweak display so that the output of _after.cpp is exactly dot0.cpp *) -(* ) - -(* Part 2: *) -let _ = if part = 2 then Run.script_cpp ~filename:"vv1.cpp" (fun () -> -*) - (* Why nbMulti? !! Accesses.shift_var ~inv:true ~factor:(trm_find_var "d" []) [nbMulti; cVarDef "t"]; *) Accesses.shift_var ~inv:true ~factor:(trm_find_var "d" []) [cFor "bi"; cVarDef "t"]; Variable.inline [cVarDef "d"]; Arith.simpl_surrounding_expr Arith.gather_rec [nbMulti; cVar "s"]; ); -(* ) - -(* Part 3: *) -let _ = if part = 3 then Run.script_cpp ~filename:"vv2.cpp" (fun () -> -*) - (* !! Resources.loop_minimize [cFor "i"]; *) !! Loop.hoist [cVarDef "t"]; !! Loop.fission [tBefore; cFor "bi"; cWriteVar "s"]; @@ -57,182 +35,3 @@ let _ = if part = 3 then Run.script_cpp ~filename:"vv2.cpp" (fun () -> !! Cleanup.std(); (* includes: !! Function.use_infix_ops ~indepth:true []; *) ) - - -(*============================HIGH LEVEL VIEW OF THE SCRIPT ============== - -s = 0 -__ghost(0 = reduce(0,0,f) à réécrire dans s ~> 0 pour avoir s ~> reduce(0,0,..)) -for i - __invariant "s ~> reduce(0,i,...)" - s += a[i] * b[i] - __ghost(reduce(0,i,f) + f(i) = reduce(0,i+1,f) à réécrire dans le contenu de s) - ---- unfold infix ops - -s = 0 -for i - __invariant "s ~> reduce(0,i,...)" - s = s + a[i] * b[i] - ---- tile -const int NB_BLOCK = a.length/B // to insert! with check divisibility? -s = 0 -for b = 0 to NB_BLOCK - __invariant "s ~> reduce(0,b*B,...)" - for i = b*B to (b+1)*B - __invariant "s ~> reduce(0,i,...)" - s = s + a[i] * b[i] - __ghost(reduce(0,i,f) + f(i) = reduce(0,i+1,f) à réécrire dans le contenu de s) - ---- local name - -s = 0 -for b - __invariant "s ~> reduce(0,b*B,...)" - t = s - // ghost(hide_cell, consume s~>v, produces "hidden(s,t)") - for i = b*B to (b+1)*B - __invariant "t ~> reduce(0,i,...)" - t = t + a[i] * b[i] - __ghost(reduce(0,i,f) + f(i) = reduce(0,i+1,f) à réécrire dans le contenu de t) - s = t - // ghost(hide_rev_cell, consume hidden(s,t), consume(t->w), produces "s~>w") - ---- insert def 'p' for the contents of 's' - -s = 0 -for b - __invariant "s ~> reduce(0,b*B,...)" - const int p = s; // sum of the prefix upto the block b - // in ctx, we have an alias: "p := reduce(0,b*B,...)" - t = s - for i = b*B to (b+1)*B - __invariant "t ~> reduce(0,i,...)" - t = t + a[i] * b[i] - __ghost(reduce(0,i,f) + f(i) = reduce(0,i+1,f) à réécrire dans le contenu de t) - s = t - ---- shift_var t by p - -s = 0 -for b - __invariant "s ~> reduce(0,b*B,...)" - const int p = s - // in ctx, we have an alias: "p := reduce(0,b*B,...)" - t = s - p // -p on write into t - for i = b*B to (b+1)*B - __invariant "t ~> reduce(0,i,...) - p" // -p on models of t - t = ((t + p) + a[i] * b[i]) - p // +p on reads on t, -p on write into t - // ICI problème: on avait - // __ghost(reduce(0,i,f) + f(i) = reduce(0,i+1,f) à réécrire dans le contenu de t) - // et maintenant il faut - // __ghost(reduce(0,i,f) - p + p + f(i) - p = reduce(0,i+1,f) - p à réécrire dans le contenu de t) - // ça je sais pas trop comment on va gérer... peut être sans typer les étapes intermédiaires ? - // parce que après on retrouve un moment où la ghost d'origine fonctionne telle quelle - s = t + p // +p on reads on t - - ---- unfold def of 'p' in the code (not in formulae), using the fact that s is not modified in the scope - -s = 0 -for b - __invariant "s ~> reduce(0,b*B,...)" - const int p = s - // in ctx, we have an alias: "p := reduce(0,b*B,...)" - t = s - s - // in ctx, we have t ~> reduce(0,b*B,...) - reduce(0,b*B,...) - for i = b*B to (b+1)*B - __invariant "t ~> reduce(0,i,...) - p" - t = ((t + s) + a[i] * b[i]) - s - // ... ici la ghost qui va bien - s = t + s - --- remove s from the block-processing by arith_simpl - -s = 0 -for b - __invariant "s ~> reduce(0,b*B,...)" - const int p = s - // in ctx, we have an alias: "p := reduce(0,b*B,...)" - t = 0 - // HERE: need to insert a ghost rewriting "0" into "reduce(0,b*B,...) - reduce(0,b*B,...)" in contents of t - for i = b*B to (b+1)*B - __invariant "t ~> reduce(0,i,...) - p" - t = t + a[i] * b[i] - // la ghost d'accumulation fonctionne de nouveau ! - __ghost(reduce(0,i,f) + f(i) = reduce(0,i+1,f) à réécrire dans le contenu de t) - s = t + s - ---- optional step: turn "p" into ghost def; --- alternative: inline "p", replacing it with "reduce(0,b*B,...)" in the formulae --- if we do nothing, it's fine too, but we'll need to duplicate "const int p = s" - when we do the fusion step later. - -s = 0 -for b - __invariant "s ~> reduce(0,b*B,...)" - // BEFORE: - // const int p = s // where p is not used in the code, only in formulae - // in ctx, we have an alias: "p := reduce(0,b*B,...)" - // AFTER: - // __DEF(p, "reduce(0,b*B,...)"); - ... - - ==> in fine, I think inlining 'p' into 'reduce(0,b*B,...)' in formulae would be easiest. - - ---- hoist de t - -s = 0 -alloc t as an array of NB_BLOCK -for b - __xmodifies "t ~> UninitCell" // pas de spécification du modèle d'entrée ou de sortie - __invariant "s ~> reduce(0,b*B,...)" - t[b] = 0 - // ghost rewriting "0" into "reduce(0,b*B,...) - reduce(0,b*B,...)" in contents of t - for i = b*B to (b+1)*B - __invariant "t[b] ~> reduce(0,i,...) - reduce(0,b*B,...)" // MODIFIED CONTRACT: t becomes t[b] - t[b] = t[b] + a[i] * b[i] - __ghost(reduce(0,i,f) + f(i) = reduce(0,i+1,f) à réécrire dans le contenu de t) - // NOTE: at this point, the ctx stores t[b] ~> reduce(0,i,...) - reduce(0,b*B,...) - // the value of t[b] determines the contract for the fission that comes next - s = t[b] + s - - ---- fission + parallelization - -s = 0 -alloc t as an array of NB_BLOCK -parallel for b - __xmodifies "t[b] ~> t[b] ~> reduce(0,i,...) - reduce(0,b*B,...)" // NEW CONTRACT! - __DEF(p, "reduce(0,b*B,...)"); - t[b] = 0 - // ghost rewriting "0" into "reduce(0,b*B,...) - reduce(0,b*B,...)" in contents of t - for i = b*B to (b+1)*B - __invariant "t ~> reduce(0,i,...) - reduce(0,b*B,...)" - t[b] = t[b] + a[i] * b[i] - __ghost(reduce(0,i,f) + f(i) = reduce(0,i+1,f) à réécrire dans le contenu de t) -for b - // MOVED: contract on 's' is just moved here - __invariant "s ~> reduce(0,b*B,...)" - s = t[b] + s - - ---- cleanup, with infix ops - -s = 0 -alloc t as an array of NB_BLOCK -parallel for b - t[b] = 0 - for i = b*B to (b+1)*B - t[b] += a[i] * b[i] -for b - s += t[b] - - -===================== -# remark: it seems that we never need to exploit - "reduce(0,i,f) - reduce(0,j,f) = reduce(j,i,f)" - -*) diff --git a/case_studies/dot_product/dot_exp.cpp b/case_studies/dot_product/dot_exp.cpp index 217458f92..fe4f8bc05 100644 --- a/case_studies/dot_product/dot_exp.cpp +++ b/case_studies/dot_product/dot_exp.cpp @@ -8,7 +8,7 @@ float dot(float* a, float* b, int n) { #pragma omp parallel for for (int bi = 0; bi < exact_div(n, 32); bi++) { t[bi] = ({ - float arith_res = 0; + float arith_res = 0.f; const float arith_res1 = arith_res; arith_res1; }); diff --git a/case_studies/gpu/matmul/matmul.ml b/case_studies/gpu/matmul/matmul.ml index fb4bff1b9..4e8e58739 100644 --- a/case_studies/gpu/matmul/matmul.ml +++ b/case_studies/gpu/matmul/matmul.ml @@ -72,6 +72,6 @@ let _ = Run.script_cpp_stage stage_ok (fun () -> [cFor ~body:[cPlusEq ~lhs:[cVar "sum"] ()] "k"]; !! Loop.simd [nbMulti; cFor ~body:[cPlusEq ~lhs:[cVar "s"] ()] "j"]; !! Loop.parallel [nbMulti; cFunBody ""; cStrict; cFor ""]; - !! Loop.unroll ~simpl:Arith.do_nothing [cFor ~body:[cPlusEq ~lhs:[cVar "s"] ()] "k"]; + !! Loop.unroll ~simpl:Arith.no_simpl [cFor ~body:[cPlusEq ~lhs:[cVar "s"] ()] "k"]; *) ) diff --git a/case_studies/matmul/.gitignore b/case_studies/matmul/.gitignore index b4a9da2a3..7a5c00e99 100644 --- a/case_studies/matmul/.gitignore +++ b/case_studies/matmul/.gitignore @@ -3,3 +3,5 @@ config/ matmul.c tvm_code tvm_ir +results +uv.lock diff --git a/case_studies/matmul/matmul_check.ml b/case_studies/matmul/matmul_check.ml index dfda4ed48..164e8d4c2 100644 --- a/case_studies/matmul/matmul_check.ml +++ b/case_studies/matmul/matmul_check.ml @@ -29,6 +29,6 @@ let _ = Run.script_cpp (fun () -> [cFor ~body:[cPlusEq ~lhs:[cVar "sum"] ()] "k"]; !! Loop.simd [nbMulti; cFor ~body:[cPlusEq ~lhs:[cVar "s"] ()] "j"]; !! Loop.parallel [nbMulti; cFunBody ""; cStrict; cFor ""]; - !! Loop.unroll ~simpl:Arith.do_nothing [cFor ~body:[cPlusEq ~lhs:[cVar "s"] ()] "k"]; + !! Loop.unroll ~simpl:Arith.no_simpl [cFor ~body:[cPlusEq ~lhs:[cVar "s"] ()] "k"]; !! Cleanup.std (); ) diff --git a/case_studies/matmul/matmul_models.cpp b/case_studies/matmul/matmul_models.cpp index 70cc2b297..cefa32eb7 100644 --- a/case_studies/matmul/matmul_models.cpp +++ b/case_studies/matmul/matmul_models.cpp @@ -31,8 +31,8 @@ void mm(float* c, float* a, float* b, int m, int n, int p) { __GHOST_END(focusA); __GHOST_END(focusB); - __ghost(in_range_bounds, "k", "k_gt_0 <- lower_bound"); // TODO: proper name k_ge_0 - __ghost(rewrite_float_linear, "inside := fun v -> &sum ~~> v, by := reduce_sum_add_right(k, fun k -> A(i, k) *. B(k, j), k_gt_0)"); + __ghost(in_range_bounds, "k", "k_ge_0 <- lower_bound"); + __ghost(rewrite_float_linear, "inside := fun v -> &sum ~~> v, by := reduce_sum_add_right(k, fun k -> A(i, k) *. B(k, j), k_ge_0)"); } c[MINDEX2(m, n, i, j)] = sum; diff --git a/case_studies/matmul/matmul_models.ml b/case_studies/matmul/matmul_models.ml index 94eee24d5..8a72063d2 100644 --- a/case_studies/matmul/matmul_models.ml +++ b/case_studies/matmul/matmul_models.ml @@ -2,10 +2,10 @@ open Optitrust open Prelude let _ = Flags.check_validity := true -let _ = Flags.pretty_matrix_notation := true -let _ = Flags.recompute_resources_between_steps := true +let _ = Flags.pretty_matrix_notation := false +let _ = Flags.recompute_resources_between_steps := false let _ = Flags.disable_stringreprs := true -let _ = Flags.save_ast_for_steps := Some Flags.Steps_important +let _ = Flags.save_ast_for_steps := Some Flags.Steps_script (* let _ = Flags.report_exectime := true *) @@ -30,5 +30,5 @@ let _ = Run.script_cpp (fun () -> [cFor ~body:[cPlusEq ~lhs:[cVar "sum"] ()] "k"]; !! Loop.simd [nbMulti; cFor ~body:[cPlusEq ~lhs:[cVar "s"] ()] "j"]; !! Loop.parallel [nbMulti; cFunBody ""; cStrict; cFor ""]; - !! Loop.unroll ~simpl:Arith.do_nothing [cFor ~body:[cPlusEq ~lhs:[cVar "s"] ()] "k"]; + !! Loop.unroll ~simpl:Arith.no_simpl [cFor ~body:[cPlusEq ~lhs:[cVar "s"] ()] "k"]; ) diff --git a/case_studies/matmul/matmul_opt_gotoblas.cpp b/case_studies/matmul/matmul_opt_gotoblas.cpp new file mode 100644 index 000000000..b835bd5ec --- /dev/null +++ b/case_studies/matmul/matmul_opt_gotoblas.cpp @@ -0,0 +1,69 @@ +#include +#include "omp.h" +// NOTE: using pretty matrix notation + +// restrict, __aligned__(256) +void mm1024(float* C, float* A, float* B) { +// MISSING: for bbj for bbk + // IMPLICITLY in L2 ? + float* const pB = (float*)malloc(1048576 * sizeof(float)); +#pragma omp parallel for + for (int bj = 0; bj < 32; bj++) { + for (int bk = 0; bk < 256; bk++) { + for (int k = 0; k < 4; k++) { + for (int j = 0; j < 32; j++) { + pB[32768 * bj + 128 * bk + 32 * k + j] = + B[32 * bj + 4096 * bk + 1024 * k + j]; + } + } + } + } + // IN GOTOBLAS: can also pack/pad A at L1 level +#pragma omp parallel for + for (int bi = 0; bi < 32; bi++) { + for (int bj = 0; bj < 32; bj++) { + // IN GOTOBLAS: direct from/to C, without 'sum' + float* const sum = (float*)malloc(1024 * sizeof(float)); + for (int i = 0; i < 32; i++) { + for (int j = 0; j < 32; j++) { + sum[32 * i + j] = 0.f; + } + } + for (int bk = 0; bk < 256; bk++) { + // MICRO KERNEL: + for (int i = 0; i < 32; i++) { + float s[32]; + MATRIX1_COPY_float(s, &sum[32 * i], 32); +#pragma omp simd + for (int j = 0; j < 32; j++) { + s[j] += A[32768 * bi + 4 * bk + 1024 * i] * + pB[32768 * bj + 128 * bk + j]; + } +#pragma omp simd + for (int j = 0; j < 32; j++) { + s[j] += A[32768 * bi + 4 * bk + 1024 * i + 1] * + pB[32768 * bj + 128 * bk + j + 32]; + } +#pragma omp simd + for (int j = 0; j < 32; j++) { + s[j] += A[32768 * bi + 4 * bk + 1024 * i + 2] * + pB[32768 * bj + 128 * bk + j + 64]; + } +#pragma omp simd + for (int j = 0; j < 32; j++) { + s[j] += A[32768 * bi + 4 * bk + 1024 * i + 3] * + pB[32768 * bj + 128 * bk + j + 96]; + } + MATRIX1_COPY_float(&sum[32 * i], s, 32); + } + } + for (int i = 0; i < 32; i++) { + for (int j = 0; j < 32; j++) { + C[32768 * bi + 32 * bj + 1024 * i + j] = sum[32 * i + j]; + } + } + free(sum); + } + } + free(pB); +} diff --git a/case_studies/opencv/box_filter_rowsum.cpp b/case_studies/opencv/box_filter_rowsum.cpp index 3050eac38..2cb942cf9 100644 --- a/case_studies/opencv/box_filter_rowsum.cpp +++ b/case_studies/opencv/box_filter_rowsum.cpp @@ -11,11 +11,9 @@ void rowSum(const int w, const uint8_t* S, uint16_t* D, const int n, const int c __writes("D ~> Matrix2(n, cn)"); for (int i = 0; i < n; i++) { // for each pixel - __sreads("S ~> Matrix2(n+w-1, cn)"); __xwrites("for c in 0..cn -> &D[MINDEX2(n, cn, i, c)] ~> Cell"); for (int c = 0; c < cn; c++) { // foreach channel - __sreads("S ~> Matrix2(n+w-1, cn)"); __xwrites("&D[MINDEX2(n, cn, i, c)] ~> Cell"); __ghost(assume, "is_subrange(i..i + w, 0..n + w - 1)"); // TODO: solve diff --git a/case_studies/opencv/box_filter_rowsum_models.cpp b/case_studies/opencv/box_filter_rowsum_models.cpp index a0f4fab4c..9bd532768 100644 --- a/case_studies/opencv/box_filter_rowsum_models.cpp +++ b/case_studies/opencv/box_filter_rowsum_models.cpp @@ -18,11 +18,9 @@ void rowSum(const int w, const int* s, int* d, const int n, const int cn) { __writes("d ~> Matrix2(n, cn, fun (i c: int) -> reduce_int_sum(i, i+w, fun k -> S(k,c)))"); for (int i = 0; i < n; i++) { // for each pixel - __sreads("s ~> Matrix2(n+w-1, cn, S)"); __xwrites("for c in 0..cn -> &d[MINDEX2(n, cn, i, c)] ~~> reduce_int_sum(i, i+w, fun k -> S(k,c))"); for (int c = 0; c < cn; c++) { // foreach channel - __sreads("s ~> Matrix2(n+w-1, cn, S)"); __xwrites("&d[MINDEX2(n, cn, i, c)] ~~> reduce_int_sum(i, i+w, fun k -> S(k,c))"); int sum = 0; diff --git a/case_studies/opencv/box_filter_rowsum_models.ml b/case_studies/opencv/box_filter_rowsum_models.ml index 06adcdc08..6b593ca5e 100644 --- a/case_studies/opencv/box_filter_rowsum_models.ml +++ b/case_studies/opencv/box_filter_rowsum_models.ml @@ -25,10 +25,6 @@ let _ = Flags.save_ast_for_steps := Some Flags.Steps_effectful let int = trm_int module Reduce = Reduce_models -let custom_specialize_simpl tg = Arith.do_nothing tg - -let no_simpl = Arith.do_nothing - (* Trace.without_resource_computation_between_steps (fun () -> Arith.default_simpl tg; @@ -39,7 +35,7 @@ let no_simpl = Arith.do_nothing let _ = Run.script_cpp (fun () -> !! Specialize.variable_multi ~mark_then:fst ~mark_else:"anyw" ["w", int 3; "w", int 5] [cFunBody "rowSum"; cFor "i"]; - !! Loop.unroll ~simpl:no_simpl [nbMulti; cMark "w"; cFor "k"]; + !! Loop.unroll ~simpl:Arith.no_simpl [nbMulti; cMark "w"; cFor "k"]; (* TODO: Reduce.unroll [nbMulti; cMark "w"; cFor "k"] + Loop.unroll + Instr.gather_targets @@ -50,10 +46,10 @@ let _ = Run.script_cpp (fun () -> !! Loop.swap [nbMulti; cMark "anyw"; cFor "i"]; !! Reduce.first_then_slide ~mark_alloc:"acc" [nbMulti; cMark "anyw"; cFor "i"]; !! Variable.elim_reuse [nbMulti; cMark "acc"]; - !! Loop.shift_range (StartAtZero) ~simpl:no_simpl [nbMulti; cMark "anyw"; cFors ["k"; "i"]]; - !! Loop.scale_range ~factor:(trm_find_var "cn" []) ~simpl:no_simpl [nbMulti; cMark "anyw"; cFors ["k"; "i"]]; + !! Loop.shift_range (StartAtZero) ~simpl:Arith.no_simpl [nbMulti; cMark "anyw"; cFors ["k"; "i"]]; + !! Loop.scale_range ~factor:(trm_find_var "cn" []) ~simpl:Arith.no_simpl [nbMulti; cMark "anyw"; cFors ["k"; "i"]]; - !! Specialize.variable_multi ~mark_then:fst ~mark_else:"anycn" ~simpl:custom_specialize_simpl + !! Specialize.variable_multi ~mark_then:fst ~mark_else:"anycn" ~simpl:Arith.no_simpl ["cn", int 1; "cn", int 3; "cn", int 4] [cMark "anyw"; cFor "c"]; !! Loop.unroll [nbMulti; cMark "cn"; cFor "c"]; @@ -64,7 +60,7 @@ let _ = Run.script_cpp (fun () -> Instr.gather_targets [c; cFor "i"; cArrayWrite "d"]; ); - !! Loop.shift_range ~simpl:no_simpl (ShiftBy (trm_find_var "c" [cMark "anycn"])) [cMark "anycn"; cFor "i"]; + !! Loop.shift_range ~simpl:Arith.no_simpl (ShiftBy (trm_find_var "c" [cMark "anycn"])) [cMark "anycn"; cFor "i"]; !! Cleanup.std (); ) diff --git a/lib/transfo/arith.ml b/lib/transfo/arith.ml index b7ef3102a..034ab4e35 100644 --- a/lib/transfo/arith.ml +++ b/lib/transfo/arith.ml @@ -48,7 +48,7 @@ let default_simpl tg = simpl_surrounding_expr (fun x -> compute (gather x)) (nbA *) let default_simpl tg = simpl_surrounding_expr gather (nbAny :: tg) -let do_nothing tg = Marks.clean ~indepth:false (nbAny :: tg) +let no_simpl tg = Marks.clean ~indepth:false (nbAny :: tg) let arith_goal_solver ((x, formula): resource_item) (evar_ctx: Resource_computation.unification_ctx): Resource_computation.unification_ctx option = let open Resource_formula in diff --git a/lib/transfo/reduce_models.ml b/lib/transfo/reduce_models.ml index f76366595..72ff8a166 100644 --- a/lib/transfo/reduce_models.ml +++ b/lib/transfo/reduce_models.ml @@ -256,6 +256,6 @@ let%transfo first_then_slide ?(mark_alloc: mark = no_mark) (tg : target) : unit Marks.with_marks (fun next_mark -> Target.iter (fun p -> let mark_loop = Marks.add_next_mark_on next_mark p in (* TODO: would need to make slide less syntax-driven to enable simpl here again *) - Loop.unroll_first_iteration ~simpl:Arith.do_nothing ~mark_loop (target_of_path p); + Loop.unroll_first_iteration ~simpl:Arith.no_simpl ~mark_loop (target_of_path p); slide ~mark_alloc [cMark mark_loop]; ) tg) diff --git a/lib/transfo/rewrite.ml b/lib/transfo/rewrite.ml index fc33900f1..e85b9de61 100644 --- a/lib/transfo/rewrite.ml +++ b/lib/transfo/rewrite.ml @@ -2,10 +2,7 @@ include Rewrite_basic open Prelude open Target -(* FIXME: move somewhere else *) -let no_simpl (tg : target) : unit = () - -let%transfo equiv_at ?(simpl : target -> unit = no_simpl) ?(glob_defs : string = "") ?(ctx : bool = false) ?(indepth : bool = false) (rule : string) (tg : target) : unit = +let%transfo equiv_at ?(simpl : target -> unit = Arith.no_simpl) ?(glob_defs : string = "") ?(ctx : bool = false) ?(indepth : bool = false) (rule : string) (tg : target) : unit = Target.reparse_after ~reparse:true (fun tg -> Marks.with_fresh_mark (fun mark -> Rewrite_basic.equiv_at ~mark ~glob_defs ~ctx ~indepth rule tg; From 913d43646ae38b04f4f796915ff2de54467b3791 Mon Sep 17 00:00:00 2001 From: Thomas Koehler Date: Wed, 1 Jul 2026 17:37:53 +0200 Subject: [PATCH 02/23] matmul GPU WIP: kernel launch; thread fors; global mem; shared mem --- case_studies/gpu/matmul/matmul.cpp | 9 +++ case_studies/gpu/matmul/matmul.ml | 93 +++++++++++++++++++++++++----- include/optitrust_gpu.h | 19 ++++++ lib/framework/show.ml | 6 +- lib/framework/target/constr.ml | 7 +++ lib/framework/target/target.ml | 8 +++ lib/transfo/gpu.ml | 3 +- lib/transfo/loop.ml | 4 +- lib/transfo/loop_basic.ml | 11 +++- lib/transfo/matrix_basic.ml | 2 +- lib/utils/list.ml | 4 ++ 11 files changed, 142 insertions(+), 24 deletions(-) diff --git a/case_studies/gpu/matmul/matmul.cpp b/case_studies/gpu/matmul/matmul.cpp index d5c5fe8f0..1fe535af5 100644 --- a/case_studies/gpu/matmul/matmul.cpp +++ b/case_studies/gpu/matmul/matmul.cpp @@ -1,4 +1,12 @@ #include +#include + +// TODO: probably shouldn't be here +__ghost(to_prove, "MSIZE2(exact_div(32, 8), exact_div(32, 4)) = MSIZE2(4, 8)"); +__ghost(to_prove, "MSIZE2(4, 8) = MSIZE2(8, 4)"); +__ghost(to_prove, "MSIZE2(8, 4) = MSIZE2(4, 8)"); +__ghost(to_prove, "MSIZE2(4, 8) = MSIZE2(exact_div(32, 8), exact_div(32, 4))"); +// ---- __DECL(reduce_sum, "int * (int -> float) -> float"); __AXIOM(reduce_sum_empty, "forall (f: int -> float) -> 0.f =. reduce_sum(0, f)"); @@ -13,6 +21,7 @@ void mm(float* c, float* a, float* b, int m, int n, int p) { __requires("A: int * int -> float, B: int * int -> float"); __reads("a ~> Matrix2(m, p, A), b ~> Matrix2(p, n, B)"); __writes("c ~> Matrix2(m, n, matmul(A, B, p))"); + __preserves("HostCtx"); for (int i = 0; i < m; i++) { __xwrites("for j in 0..n -> &c[MINDEX2(m, n, i, j)] ~~> matmul(A, B, p)(i, j)"); diff --git a/case_studies/gpu/matmul/matmul.ml b/case_studies/gpu/matmul/matmul.ml index 4e8e58739..1b5680b46 100644 --- a/case_studies/gpu/matmul/matmul.ml +++ b/case_studies/gpu/matmul/matmul.ml @@ -1,14 +1,14 @@ open Optitrust open Prelude -let _ = Flags.check_validity := true (* FIXME: this flag behaviour needs to be cleaned up *) +let _ = Flags.check_validity := true (* FIXME: this flag behaviour needs to be cleaned up. *) let _ = Flags.pretty_matrix_notation := false -let _ = Flags.recompute_resources_between_steps := true +let _ = Flags.recompute_resources_between_steps := false let _ = Flags.disable_stringreprs := true let _ = Flags.save_ast_for_steps := Some Flags.Steps_script (* let _ = Flags.report_exectime := true *) -let stage_ok = fun i -> true +let stage_ok = fun i -> i = 6 let bm = 32 let bn = 32 @@ -31,7 +31,7 @@ let _ = Run.script_cpp_stage stage_ok (fun () -> !! Matrix.local_name_tile ~uninit_pre:true ~var:"c" ~local_var:"c_gmem" [cFor "i"]; !! Matrix.local_name_tile ~uninit_post:true ~var:"a" ~local_var:"a_gmem" [cFor "i"]; !! Matrix.local_name_tile ~uninit_post:true ~var:"b" ~local_var:"b_gmem" [cFor "i"]; - (* TODO: memcpy here *) + !! Matrix.memcpy [nbMulti; cFor "i1"]; let rec tiles (loop_id, tile_name_sizes) = match tile_name_sizes with @@ -63,15 +63,80 @@ let _ = Run.script_cpp_stage stage_ok (fun () -> !! Loop.hoist_expr ~dest:[tBefore; cFor "bkIdx"; cFor "i" ~body:[cPlusEq ~lhs:[cVar "sum"] ()]] "b_regs" ~indep:["i"] [cArrayRead "b_smem"]; - !! Cleanup.std (); - (* - TODO: - - !! Loop.hoist_expr ~dest:[tBefore; cFor "bi"] "bT" ~indep:["bi"; "i"] [cArrayRead "b"]; - !! Matrix.stack_copy ~var:"sum" ~copy_var:"s" ~copy_dims:1 - [cFor ~body:[cPlusEq ~lhs:[cVar "sum"] ()] "k"]; - !! Loop.simd [nbMulti; cFor ~body:[cPlusEq ~lhs:[cVar "s"] ()] "j"]; - !! Loop.parallel [nbMulti; cFunBody ""; cStrict; cFor ""]; - !! Loop.unroll ~simpl:Arith.no_simpl [cFor ~body:[cPlusEq ~lhs:[cVar "s"] ()] "k"]; + (* !! Cleanup.std (); *) + (* NOTE (a_smem / b_smem loads): + - The first loop nest should still be reordered to move k inside (ti; i; k), which would basically be the vectorized dimension. The i index would become tj. One can also see this as collapsing ti; i as the thread flat dimension. + - The second loop nest seems to be in the right order to me, where j would basically be the vectorized dimension. The tj; k indices would become ti; tj, in other words collapse into the flat thread dimension. *) ) + +let _ = Run.script_cpp_stage stage_ok (fun () -> + (* Construct terms to pass to kernel_launch *) + (* LATER: cleaner frontend for building terms *) + let t_m, t_n, t_bm, t_bn, t_bk, t_tm, t_tn = ( + let v name = trm_find_var name [cFunDef "mm"] in + let i v = trm_int v in + (v "m", v "n", i bm, i bn, i bk, i tm, i tn) + ) in + + let tpb = [trm_exact_div_int t_bm t_tm; trm_exact_div_int t_bn t_tn] in + let bpg = [trm_exact_div_int t_m t_bm; trm_exact_div_int t_n t_bn] in + (* sizeof(float) * 32 * 32 *) + let smem_szs = [ + trm_mul_int (trm_sizeof typ_f32) + (trm_mul_int t_bk (trm_mul_int (trm_int (bm/tm)) t_tm)); + trm_mul_int (trm_sizeof typ_f32) + (trm_mul_int t_bk (trm_mul_int (trm_int (bn/tn)) t_tn)) + ] in + + (* Wrap kernel body in launch and kill calls *) + !! Gpu.create_kernel_launch bpg tpb smem_szs + ~setup_end:[tBefore; cFor "bi"] ~teardown_begin:[tAfter; cFor "bi"] + [tBefore; cVarDef "a_smem"] [tAfter; cPrimCall Prim_delete ~args:[[cVar "a_smem"]]]; + + (* !! Gpu.convert_tail_thread_for [1] [occFirst; cFor "bi"; cFor "ti"]; + !! Gpu.convert_tail_thread_for [1;1] [occFirst; cFor "bi"; cFor "bj"; cFor "ti"]; *) + + !! Gpu.convert_tail_thread_for [1] [occFirst; cFor "ti"; cFor ~body:[cWrite ~lhs:[cVar "sum"] ()] "tj"]; + !! Gpu.convert_tail_thread_for [0;1] [cFor "ti"; cFor "k"; cFor ~body:[cWrite ~lhs:[cVar "a_smem"] ()] "i"]; + !! Gpu.convert_tail_thread_for [1] [cFor "tj"; cFor ~body:[cWrite ~lhs:[cVar "b_smem"] ()] "k"]; +) + +let _ = Run.script_cpp_stage stage_ok (fun () -> + !! Gpu.convert_tail_thread_for [1] [cFor "ti"; cFor ~body:[cPlusEq ~lhs:[cVar "sum"] ()] "tj"]; (* occLast; cWrite *) + !! Gpu.convert_tail_thread_for [1] [cFor "ti"; cFor ~body:[cWrite ~lhs:[cVar "c_gmem"] ()] "tj"]; + !! Gpu.convert_tail_thread_for [1] [cFor "bi"; cFor "bj"]; +) + +let _ = Run.script_cpp_stage stage_ok (fun () -> + !! Gpu.convert_magic_thread_fors ~patch_steps:(fun () -> + Gpu.insert_threadsctx_rewrite + (Matrix_trm.msize [(trm_exact_div_int (trm_int 32) (trm_int 8)); + (trm_exact_div_int (trm_int 32) (trm_int 4))]) + (Matrix_trm.msize [(trm_int 4); (trm_int 8)]) + [tBefore; occFirst; cFor ~body:[cWrite ~lhs:[cVar "sum"] ()] "ti"]; + Gpu.insert_threadsctx_rewrite + (Matrix_trm.msize [(trm_int 4); (trm_int 8)]) + (Matrix_trm.msize [(trm_int 8); (trm_int 4)]) + [tBefore; cFor ~body:[cWrite ~lhs:[cVar "b_smem"] ()] "tj"]; + Gpu.insert_threadsctx_rewrite + (Matrix_trm.msize [(trm_int 8); (trm_int 4)]) + (Matrix_trm.msize [(trm_int 4); (trm_int 8)]) + [tBefore; cFor ~body:[cPlusEq ~lhs:[cVar "sum"] ()] "ti"]; + Gpu.insert_threadsctx_rewrite + (Matrix_trm.msize [(trm_int 4); (trm_int 8)]) + (Matrix_trm.msize [(trm_exact_div_int (trm_int 32) (trm_int 8)); + (trm_exact_div_int (trm_int 32) (trm_int 4))]) + [tLast; cForBody "bj"]; + ) [nbAny; cFunBody "mm"; cFor ""]; + + !! Gpu.convert_to_global_mem [nbMulti; cVarDefs ["a_gmem"; "b_gmem"; "c_gmem"]]; + !! Gpu.convert_to_shared_mem ~chop_dims:2 [nbMulti; cVarDefs ["a_smem"; "b_smem"]]; + + let kernel_mark = "kernel_body" in + !! Marks.add_fake_instr kernel_mark [tAfter; cCall "kernel_launch"]; + + !! Instr.delete [occFirst; cFor "bkIdx"; cCall "magic_barrier"]; + !! Gpu.insert_barrier [tFirst; cForBody "bkIdx"]; + !! Gpu.magic_barrier_to_blocksync [cMark kernel_mark] [occFirst; cFor "bkIdx"; cCall "magic_barrier"]; +) diff --git a/include/optitrust_gpu.h b/include/optitrust_gpu.h index 1e6fcfe1d..c99977e88 100644 --- a/include/optitrust_gpu.h +++ b/include/optitrust_gpu.h @@ -9,6 +9,12 @@ extern const int __magic_threadfor; extern const int __device_call; extern const int __barrier_sequence; +/* + before lowering : arithmetic operations +/- + after lowering : arithmetic operations MxN cycles, N PUs cycle 1 + @ PU1; cycle 2 - @ PU2 + + top-level for loop, unroll inner for loop +*/ + __DECL(GMem, "MemType"); __DECL(SMem, "MemType"); __DECL(TReg, "MemType"); @@ -257,6 +263,19 @@ template T* __smem_malloc2(int N1, int N2) { } #define SMEM_MALLOC2(T, N1, N2) __call_with(__smem_malloc2(N1, N2), "T := "#T) +template T* __smem_malloc3(int N1, int N2, int N3) { + __requires("tpb: int, bpg: int, smem_sz: int, smem_sz_rem: int"); + __preserves("KernelSetupCtx"); + __reads("KernelParams(bpg,tpb,smem_sz)"); + __produces("desync_for i in ..bpg -> for j1 in 0..N1 -> for j2 in 0..N2 -> for j3 in 0..N3 -> &_Res[MINDEX4(bpg, N1, N2, N3, DMINDEX1(bpg, i), j1, j2, j3)] ~> UninitCellOf(SMem)"); + __produces("Free(_Res, for i in 0..bpg -> for j1 in 0..N1 -> for j2 in 0..N2 -> for j3 in 0..N3 -> &_Res[MINDEX4(bpg, N1, N2, N3, DMINDEX1(bpg, i), j1, j2, j3)] ~> UninitCellOf(SMem))"); + __consumes("SMemToken(sizeof(T)*(N1*N2*N3))"); + __ensures("__spec_override_ret_implicit(ptr(T))"); + __admitted(); + return __alloc_sig_generic(); +} +#define SMEM_MALLOC3(T, N1, N2, N3) __call_with(__smem_malloc3(N1, N2, N3), "T := "#T) + // LATER: should be able to get away with just one smem_free, but since the Free token // doesn't store size, we can't. template void __smem_free1(T* p, int N1) { diff --git a/lib/framework/show.ml b/lib/framework/show.ml index 23a36d34f..150c285ce 100644 --- a/lib/framework/show.ml +++ b/lib/framework/show.ml @@ -76,7 +76,7 @@ let paths ?(msg : string = "") (ps : paths) : unit = (* Print terms *) -let trm ?(style = default_style ()) ?(msg : string = "") (t : trm) : unit = +let trm ?(style = optilambda ()) ?(msg : string = "") (t : trm) : unit = prt_msg msg; let prepare_encoded_term t = if style.decode then begin @@ -101,7 +101,7 @@ let trm ?(style = default_style ()) ?(msg : string = "") (t : trm) : unit = in prt ~suffix:"\n" st -let trms ?(style = default_style ()) ?(msg : string = "") (ts : trms) : unit = +let trms ?(style = optilambda ()) ?(msg : string = "") (ts : trms) : unit = prt_list ~msg (trm ~style) ts let trm_internal ?(msg : string option) (t : trm) : unit = @@ -188,7 +188,7 @@ module At = struct let path ?(msg : string = "") (tg : Target.target) : unit = at ~msg (fun p _t -> path p) tg - let trm ?(style = default_style ()) ?(msg : string = "") (tg : Target.target) : unit = + let trm ?(style = optilambda ()) ?(msg : string = "") (tg : Target.target) : unit = at_trm ~msg (trm ~style) tg let typ = at_trm (fun t -> typ_opt t.typ) diff --git a/lib/framework/target/constr.ml b/lib/framework/target/constr.ml index 28ab76027..b0afd9dc8 100644 --- a/lib/framework/target/constr.ml +++ b/lib/framework/target/constr.ml @@ -181,6 +181,8 @@ and constr = | Constr_namespace of constr_name (* Constraint to match a term when a predicate is true *) | Constr_pred of (trm -> bool) + (* Constraint to match inside a term of a given kind *) + | Constr_kind of trm_kind * target (* LATER: optimize constr_of_path; should be recognized by resolution, and processed more efficiently; checking that the start of the path @@ -384,6 +386,9 @@ let constr_map (f : constr -> constr) (c : constr) : constr = | Constr_omp _ -> c | Constr_namespace _ -> c | Constr_pred _ -> c + | Constr_kind (k, tg) -> + let s_tg = aux tg in + Constr_kind (k, s_tg) (** [get_target_regexp_kinds tgs]: gets the list of trm_kinds of the terms for which we would potentially need to use the string representation, @@ -844,6 +849,8 @@ let rec check_constraint ~(incontracts:bool) (c : constr) (t : trm) : bool = | Constr_omp (pred, _), _ -> trm_has_pragma pred t | Constr_namespace cn, Trm_namespace (name, _, _) -> check_name cn name | Constr_pred pred, _ -> pred t + | Constr_kind (k, tg), _ -> + match_regexp_trm_kind k t && check_target tg t | _ -> false (** [check_list ~incontracts ~depth lpred tl]: checks if [tl] satisfy the predicate [lpred] *) diff --git a/lib/framework/target/target.ml b/lib/framework/target/target.ml index 42808a992..509b441e8 100644 --- a/lib/framework/target/target.ml +++ b/lib/framework/target/target.ml @@ -294,6 +294,11 @@ let sExprRegexp ?(substr : bool = true) (s : string) : constr = let cPred (p : trm -> bool) : constr = Constr_pred p +let cKind (k : trm_kind) (tg : target) : constr = + Constr_kind (k, tg) + +let cInstr : target -> constr = cKind TrmKind_Instr + (** [cInclude s]: matches include directives. *) let cInclude (s : string) : constr = Constr_include s @@ -667,6 +672,9 @@ let cEnum ?(name : string = "") ?(substr : bool = false) ?(constants : (string * let cSeq ?(instrs : targets = []) ?(instrs_pred:target_list_pred = target_list_pred_default) () : constr = Constr_seq (combine_args instrs instrs_pred) +let cSeqContaining (inner_tg : target) : constr = + Constr_seq (target_list_one_st inner_tg) + (** [cVar ~regexp ~substr ~trmkind ~typ ~typ_pred name]: matches variable occurrences [regepx] - match based on regexp [substr] - match partially diff --git a/lib/transfo/gpu.ml b/lib/transfo/gpu.ml index 192de5803..2cf963ac6 100644 --- a/lib/transfo/gpu.ml +++ b/lib/transfo/gpu.ml @@ -10,8 +10,7 @@ include Gpu_basic The list [loops] is a list containing either 0 or 1: 0 means skip conversion (leave it as sequential for), 1 means convert. It is always assumed that the leaf will be converted. *) let%transfo convert_tail_thread_for (loops : int list) (leaf: target) = - let fission_helper tg = - Flags.with_flag Flags.check_validity true (fun () -> Loop.fission tg) in + let fission_helper tg = Loop.fission tg in let rec aux barrier_mark loops_incl_leaf leaf_p: unit = let convert,loops = match loops_incl_leaf with | 0 :: tl -> false, tl diff --git a/lib/transfo/loop.ml b/lib/transfo/loop.ml index e085d18e6..eb19eb736 100644 --- a/lib/transfo/loop.ml +++ b/lib/transfo/loop.ml @@ -38,7 +38,7 @@ let rec fission_rec (next_mark : unit -> mark) (nest_of : int) (m_interstice : m else if i = Mlist.length loop_body_instrs then Marks.add m_between [cPath p_loop; tAfter] else begin - let m_interstice = if !Flags.check_validity then begin (* FIXME: hide condition between better API? *) + let m_interstice = if !Flags.check_validity || !Flags.use_resources_with_models then begin (* FIXME: hide condition between better API? *) let m = next_mark () in Ghost_pair.fission ~mark_between:m (target_of_path p_interstice); Ghost_pure.fission ~mark_clears:m_clears [cPath p_loop_body; cMark m]; @@ -53,7 +53,7 @@ let rec fission_rec (next_mark : unit -> mark) (nest_of : int) (m_interstice : m (* TODO: this is required if other transformations like Variable_basic.inline don't eagerly do it. *) Resources.make_strict_loop_contracts [cPath p_loop]; fission_basic ~mark_loops:m_loops ~mark_between_loops:m_between [cPath p_loop_body; cMark m_interstice]; - if !Flags.check_validity then begin (* FIXME: hide condition between better API? *) + if !Flags.check_validity || !Flags.use_resources_with_models then begin (* FIXME: hide condition between better API? *) Ghost_pair.minimize_all_in_seq [nbExact 2; cPath p_outer_seq; cMark m_loops; dBody]; Resources.loop_minimize [nbExact 2; cPath p_outer_seq; cMark m_loops]; Ghost_pure.remove_clears m_clears [occFirst; cPath p_outer_seq; cMark m_loops; dBody]; diff --git a/lib/transfo/loop_basic.ml b/lib/transfo/loop_basic.ml index 918150c26..4b3165a8b 100644 --- a/lib/transfo/loop_basic.ml +++ b/lib/transfo/loop_basic.ml @@ -277,7 +277,7 @@ let fission_on_as_pair (mark_loops : mark) (index : int) (t : trm) : trm * trm = let tl, _ = trm_inv trm_seq_inv t_seq in let tl1, _, tl2 = Mlist.split_on_marks index tl in let fst_contract, snd_contract = - if not !Flags.check_validity then + if not (!Flags.check_validity || !Flags.use_resources_with_models) then empty_loop_contract, empty_loop_contract else let open Resource_formula in @@ -342,6 +342,7 @@ let fission_on_as_pair (mark_loops : mark) (index : int) (t : trm) : trm * trm = | None -> acc ) Var_set.empty tl1 in + (* DEBUG Printf.printf "bound_in_tl1: %s\n" (vars_to_string (Var_set.elements bound_in_tl1)); *) let split_res_comm = List.filter (fun (h, formula) -> Var_set.disjoint (trm_free_vars formula) bound_in_tl1 ) split_res_comm @@ -359,13 +360,18 @@ let fission_on_as_pair (mark_loops : mark) (index : int) (t : trm) : trm * trm = failwith "The resources at split point depend on the variable %s created before in the sequence" (var_to_string x) | Some Ensured when Var_map.mem x usage_after_tl1 && + (* (not (Var_set.mem x bound_in_tl1)) && *) Var_set.disjoint (trm_free_vars f) bound_in_tl1 -> + (* DEBUG Printf.printf "%s\n" (Resource_computation.named_formula_to_string (x, f)); *) true | _ -> false ) split_res.pure in let middle_iter_contract = Resource_set.copy (Resource_set.make ~pure:tl1_ensured ~linear:split_res_comm ()) in + (* DEBUG + Printf.printf "middle_iter_contract: %s\n" (Resource_computation.resource_set_to_string middle_iter_contract); *) + let fst_contract = { loop_ghosts = contract.loop_ghosts; invariant = { contract.invariant with linear = tl1_inv }; @@ -421,7 +427,8 @@ let%transfo fission_basic ?(mark_loops : mark = no_mark) ?(mark_between_loops : (* DEBUG: let debug_p = Path.parent p_loop in Show.res ~msg:"res1" ~ast:(get_trm_at_exn (target_of_path debug_p)) ); *) - Resources.required_for_check (); + if !Flags.check_validity || !Flags.use_resources_with_models + then Resources.ensure_computed (); apply_at_path (fission_on mark_loops mark_between_loops split_i) p_loop; ) tg ); diff --git a/lib/transfo/matrix_basic.ml b/lib/transfo/matrix_basic.ml index 8d2fe071a..b33d48201 100644 --- a/lib/transfo/matrix_basic.ml +++ b/lib/transfo/matrix_basic.ml @@ -259,7 +259,7 @@ let%transfo local_name_tile Nobrace_transfo.remove_after (fun _ -> Target.iter (fun p -> Marks.with_fresh_mark_on p (fun m -> let tile_dims_typ_model = ref None in - if !Flags.check_validity then begin + if !Flags.check_validity || !Flags.use_resources_with_models then begin (* find groups of mindex resource over !ret_var in context *) Resources.ensure_computed (); let var = !ret_var in diff --git a/lib/utils/list.ml b/lib/utils/list.ml index 7913fbc9d..a6dbdd1ed 100644 --- a/lib/utils/list.ml +++ b/lib/utils/list.ml @@ -25,6 +25,10 @@ let iteri2 (f : int -> 'a -> 'b -> unit) (al : 'a list) (bl : 'b list) : unit = let all_true (bl : bool list) : bool = for_all (fun b -> b = true) bl +(** [list_any_true bl]: returns [true] if any boolean in the list [bl] is [true]. *) +let any_true (bl : bool list) : bool = + exists (fun b -> b = true) bl + (** [split_at n l]: splits the list [l] just before the element at index [n], and return the two sublists (which could be empty). *) let split_at (i : int) (l : 'a list) : ('a list) * ('a list) = From 952acd129c1cbe1c9dc437ceeb11573153e8975e Mon Sep 17 00:00:00 2001 From: Thomas Koehler Date: Thu, 2 Jul 2026 18:30:06 +0200 Subject: [PATCH 03/23] autofree and thread registers --- case_studies/gpu/matmul/matmul.cpp | 1 + case_studies/gpu/matmul/matmul.ml | 27 +++++--- include/optitrust_gpu.h | 46 +++++++++++-- lib/ast/gpu_trm.ml | 5 ++ .../resources/resource_computation.ml | 35 ++++++---- lib/framework/resources/resource_formula.ml | 13 ++++ lib/framework/resources/resource_trm.ml | 5 ++ lib/transfo/gpu.ml | 19 ++++++ lib/transfo/gpu_basic.ml | 65 +++++++++++++++++-- 9 files changed, 182 insertions(+), 34 deletions(-) diff --git a/case_studies/gpu/matmul/matmul.cpp b/case_studies/gpu/matmul/matmul.cpp index 1fe535af5..f7d072f56 100644 --- a/case_studies/gpu/matmul/matmul.cpp +++ b/case_studies/gpu/matmul/matmul.cpp @@ -19,6 +19,7 @@ __DEF(matmul, "fun (A B: int * int -> float) (p: int) -> fun (i j: int) -> reduc */ void mm(float* c, float* a, float* b, int m, int n, int p) { __requires("A: int * int -> float, B: int * int -> float"); + __requires("m >= 0, n >= 0, p >= 0"); // <-- should be derived from matrix dimension constraint ? __reads("a ~> Matrix2(m, p, A), b ~> Matrix2(p, n, B)"); __writes("c ~> Matrix2(m, n, matmul(A, B, p))"); __preserves("HostCtx"); diff --git a/case_studies/gpu/matmul/matmul.ml b/case_studies/gpu/matmul/matmul.ml index 1b5680b46..706c75dbb 100644 --- a/case_studies/gpu/matmul/matmul.ml +++ b/case_studies/gpu/matmul/matmul.ml @@ -70,6 +70,8 @@ let _ = Run.script_cpp_stage stage_ok (fun () -> *) ) +let _ = Flags.check_validity := false + let _ = Run.script_cpp_stage stage_ok (fun () -> (* Construct terms to pass to kernel_launch *) (* LATER: cleaner frontend for building terms *) @@ -84,9 +86,9 @@ let _ = Run.script_cpp_stage stage_ok (fun () -> (* sizeof(float) * 32 * 32 *) let smem_szs = [ trm_mul_int (trm_sizeof typ_f32) - (trm_mul_int t_bk (trm_mul_int (trm_int (bm/tm)) t_tm)); + (trm_mul_int (trm_mul_int t_bk (trm_int (bm/tm))) t_tm); trm_mul_int (trm_sizeof typ_f32) - (trm_mul_int t_bk (trm_mul_int (trm_int (bn/tn)) t_tn)) + (trm_mul_int (trm_mul_int (trm_int (bn/tn)) t_bk) t_tn) ] in (* Wrap kernel body in launch and kill calls *) @@ -94,9 +96,6 @@ let _ = Run.script_cpp_stage stage_ok (fun () -> ~setup_end:[tBefore; cFor "bi"] ~teardown_begin:[tAfter; cFor "bi"] [tBefore; cVarDef "a_smem"] [tAfter; cPrimCall Prim_delete ~args:[[cVar "a_smem"]]]; - (* !! Gpu.convert_tail_thread_for [1] [occFirst; cFor "bi"; cFor "ti"]; - !! Gpu.convert_tail_thread_for [1;1] [occFirst; cFor "bi"; cFor "bj"; cFor "ti"]; *) - !! Gpu.convert_tail_thread_for [1] [occFirst; cFor "ti"; cFor ~body:[cWrite ~lhs:[cVar "sum"] ()] "tj"]; !! Gpu.convert_tail_thread_for [0;1] [cFor "ti"; cFor "k"; cFor ~body:[cWrite ~lhs:[cVar "a_smem"] ()] "i"]; !! Gpu.convert_tail_thread_for [1] [cFor "tj"; cFor ~body:[cWrite ~lhs:[cVar "b_smem"] ()] "k"]; @@ -114,7 +113,9 @@ let _ = Run.script_cpp_stage stage_ok (fun () -> (Matrix_trm.msize [(trm_exact_div_int (trm_int 32) (trm_int 8)); (trm_exact_div_int (trm_int 32) (trm_int 4))]) (Matrix_trm.msize [(trm_int 4); (trm_int 8)]) - [tBefore; occFirst; cFor ~body:[cWrite ~lhs:[cVar "sum"] ()] "ti"]; + [tBefore; cVarDef "sum"]; + (* NOTE: need to be before the sum alloc for later conversion + [tBefore; occFirst; cFor ~body:[cWrite ~lhs:[cVar "sum"] ()] "ti"]; *) Gpu.insert_threadsctx_rewrite (Matrix_trm.msize [(trm_int 4); (trm_int 8)]) (Matrix_trm.msize [(trm_int 8); (trm_int 4)]) @@ -132,11 +133,19 @@ let _ = Run.script_cpp_stage stage_ok (fun () -> !! Gpu.convert_to_global_mem [nbMulti; cVarDefs ["a_gmem"; "b_gmem"; "c_gmem"]]; !! Gpu.convert_to_shared_mem ~chop_dims:2 [nbMulti; cVarDefs ["a_smem"; "b_smem"]]; + !! Gpu.convert_to_register_mem ~chop_dims:2 [cVarDef "sum"]; + !! Gpu.convert_to_register_mem ~chop_dims:0 [nbMulti; cVarDefs ["a_regs"; "b_regs"]]; let kernel_mark = "kernel_body" in !! Marks.add_fake_instr kernel_mark [tAfter; cCall "kernel_launch"]; - !! Instr.delete [occFirst; cFor "bkIdx"; cCall "magic_barrier"]; - !! Gpu.insert_barrier [tFirst; cForBody "bkIdx"]; - !! Gpu.magic_barrier_to_blocksync [cMark kernel_mark] [occFirst; cFor "bkIdx"; cCall "magic_barrier"]; + !! Instr.delete [occFirst; cCall "magic_barrier"]; + !! Instr.delete [occFirst; cCall "magic_barrier"]; + (* FIXME: !! Instr.delete [occIndex 1; cCall "magic_barrier"]; *) + !! Gpu.magic_barrier_to_blocksync [cMark kernel_mark] [nbMulti; cFor "bkIdx"; cCall "magic_barrier"]; + (* TODO: barrier option 2 + !! Gpu.insert_barrier [tFirst; cForBody "bkIdx"]; *) + + !! Instr.move ~dest:[tAfter; cCall "kernel_teardown_begin"] [cCall "magic_barrier"]; + !! Gpu.magic_barrier_to_teardown_sync [cCall "magic_barrier"]; ) diff --git a/include/optitrust_gpu.h b/include/optitrust_gpu.h index c99977e88..00468d16b 100644 --- a/include/optitrust_gpu.h +++ b/include/optitrust_gpu.h @@ -300,12 +300,24 @@ template void __smem_free2(T* p, int N1, int N2) { __admitted(); } +template void __smem_free3(T* p, int N1, int N2, int N3) { + __requires("tpb: int, bpg: int, smem_sz: int"); + __preserves("KernelTeardownCtx"); + __reads("KernelParams(bpg,tpb,smem_sz)"); + __consumes("for i in 0..bpg -> for j1 in 0..N1 -> for j2 in 0..N2 -> for j3 in 0..N3 -> &p[MINDEX4(bpg, N1, N2, N3, DMINDEX1(bpg, i), j1, j2, j3)] ~> UninitCellOf(SMem)"); + __consumes("Free(p, for i in 0..bpg -> for j1 in 0..N1 -> for j2 in 0..N2 -> for j3 in 0..N3 -> &p[MINDEX4(bpg, N1, N2, N3, DMINDEX1(bpg, i), j1, j2, j3)] ~> UninitCellOf(SMem))"); + __produces("SMemToken(sizeof(T)*(N1*N2*N3))"); + __ensures("__spec_override_noret()"); + __admitted(); +} + // Thread registers template T* __treg_ref(T v) { __requires("t: int, sz: int"); __preserves("ThreadsCtx(t..+sz)"); __produces("desync_for i in ..sz -> &_Res[MINDEX1(sz, DMINDEX1(sz, i))] ~~>[TReg] v"); + __produces("AutoFree(_Res, desync_for i in ..sz -> &_Res[MINDEX1(sz, DMINDEX1(sz, i))] ~> UninitCellOf(TReg))"); __ensures("__spec_override_ret_implicit(ptr(T))"); __admitted(); return __alloc_sig_generic(); @@ -332,25 +344,21 @@ template T* __treg_ref_uninit0() { __requires("t: int, sz: int"); __preserves("ThreadsCtx(t..+sz)"); __produces("desync_for i in ..sz -> &_Res[MINDEX1(sz, DMINDEX1(sz, i))] ~> UninitCellOf(TReg)"); + __produces("AutoFree(_Res, desync_for i in ..sz -> &_Res[MINDEX1(sz, DMINDEX1(sz, i))] ~> UninitCellOf(TReg))"); __ensures("__spec_override_ret_implicit(ptr(T))"); __admitted(); return __alloc_sig_generic(); } #define TREG_REF_UNINIT0(T) __call_with(__treg_ref_uninit0(), "T := "#T) -// specialized version of above with singleton ghost built in template T* __treg_ref_uninit0_s() { __requires("t: int"); __preserves("ThreadsCtx(t..+MSIZE0())"); __produces("_Res ~> UninitCellOf(TReg)"); + __produces("AutoFree(_Res, _Res ~> UninitCellOf(TReg))"); __ensures("__spec_override_ret_implicit(ptr(T))"); - // admitted for now because proper autofree/typechecking for TReg is not implemented __admitted(); - // but these steps should be correct - T* const p = TREG_REF_UNINIT0(T); - __ghost(unwrap_singleton_desyncgroup, "H := fun i -> &p[MINDEX1(MSIZE0(), DMINDEX1(MSIZE0(), i))] ~> UninitCellOf(TReg)"); - __ghost(singleton_mindex_simplify, "H := fun p -> p ~> UninitCellOf(TReg), p := p"); - return p; + return __alloc_sig_generic(); } #define TREG_REF_UNINIT0_S(T) __call_with(__treg_ref_uninit0_s(), "T := "#T) @@ -358,22 +366,46 @@ template T* __treg_ref_uninit1(int N1) { __requires("t: int, sz: int"); __preserves("ThreadsCtx(t..+sz)"); __produces("desync_for i in ..sz -> for j1 in 0..N1 -> &_Res[MINDEX2(sz, N1, DMINDEX1(sz, i), j1)] ~> UninitCellOf(TReg)"); + __produces("AutoFree(_Res, desync_for i in ..sz -> for j1 in 0..N1 -> &_Res[MINDEX2(sz, N1, DMINDEX1(sz, i), j1)] ~> UninitCellOf(TReg))"); __ensures("__spec_override_ret_implicit(ptr(T))"); __admitted(); return __alloc_sig_generic(); } #define TREG_REF_UNINIT1(T, N1) __call_with(__treg_ref_uninit1(N1), "T := "#T) +template T* __treg_ref_uninit1_s(int N1) { + __requires("t: int"); + __preserves("ThreadsCtx(t..+MSIZE0())"); + __produces("for j1 in 0..N1 -> &_Res[MINDEX1(N1, j1)] ~> UninitCellOf(TReg)"); + __produces("AutoFree(_Res, for j1 in 0..N1 -> &_Res[MINDEX1(N1, j1)] ~> UninitCellOf(TReg))"); + __ensures("__spec_override_ret_implicit(ptr(T))"); + __admitted(); + return __alloc_sig_generic(); +} +#define TREG_REF_UNINIT1_S(T) __call_with(__treg_ref_uninit1_s(), "T := "#T) + template T* __treg_ref_uninit2(int N1, int N2) { __requires("t: int, sz: int"); __preserves("ThreadsCtx(t..+sz)"); __produces("desync_for i in ..sz -> for j1 in 0..N1 -> for j2 in 0..N2 -> &_Res[MINDEX3(sz, N1, N2, DMINDEX1(sz, i), j1, j2)] ~> UninitCellOf(TReg)"); + __produces("AutoFree(_Res, desync_for i in ..sz -> for j1 in 0..N1 -> for j2 in 0..N2 -> &_Res[MINDEX3(sz, N1, N2, DMINDEX1(sz, i), j1, j2)] ~> UninitCellOf(TReg))"); __ensures("__spec_override_ret_implicit(ptr(T))"); __admitted(); return __alloc_sig_generic(); } #define TREG_REF_UNINIT2(T, N1, N2) __call_with(__treg_ref_uninit2(N1, N2), "T := "#T) +template T* __treg_ref_uninit2_s(int N1, int N2) { + __requires("t: int"); + __preserves("ThreadsCtx(t..+MSIZE0())"); + __produces("for j1 in 0..N1 -> for j2 in 0..N2 -> &_Res[MINDEX2(N1, N2, j1, j2)] ~> UninitCellOf(TReg)"); + __produces("AutoFree(_Res, for j1 in 0..N1 -> for j2 in 0..N2 -> &_Res[MINDEX2(N1, N2, j1, j2)] ~> UninitCellOf(TReg))"); + __ensures("__spec_override_ret_implicit(ptr(T))"); + __admitted(); + return __alloc_sig_generic(); +} +#define TREG_REF_UNINIT2_S(T) __call_with(__treg_ref_uninit2_s(), "T := "#T) + template T __treg_get(T* p) { __requires("v: T, t: int"); __reads("ThreadsCtx(t ..+ MSIZE0())"); diff --git a/lib/ast/gpu_trm.ml b/lib/ast/gpu_trm.ml index 4d57af460..3fb07b962 100644 --- a/lib/ast/gpu_trm.ml +++ b/lib/ast/gpu_trm.ml @@ -102,8 +102,13 @@ let var__smem_malloc nb_dims = (* NOTE: terms for thread registers have been added, as we attempted to add a quick hack to the typechecker for automatic freeing of TReg resources (c07b695), but it was unsound, so the typechecker support was removed, while the term definitions still remain. *) +let var_treg = toplevel_var "TReg" +let var__treg_get = toplevel_var "__treg_get" +let var__treg_set = toplevel_var "__treg_set" let var__treg_ref = toplevel_var "__treg_ref" let var__treg_ref_s = toplevel_var "__treg_ref_s" let var__treg_ref_uninit0_s = toplevel_var "__treg_ref_uninit0_s" let var__treg_ref_uninit = Matrix_trm.toplevel_var_with_dim "__treg_ref_uninit%d" let var__treg_ref_uninit_inv = Matrix_trm.toplevel_var_with_dim_inv var__treg_ref_uninit +let var__treg_ref_uninit_s = Matrix_trm.toplevel_var_with_dim "__treg_ref_uninit%d_s" +let var__treg_ref_uninit_s_inv = Matrix_trm.toplevel_var_with_dim_inv var__treg_ref_uninit_s diff --git a/lib/framework/resources/resource_computation.ml b/lib/framework/resources/resource_computation.ml index dbb954315..c6fe09589 100644 --- a/lib/framework/resources/resource_computation.ml +++ b/lib/framework/resources/resource_computation.ml @@ -333,7 +333,7 @@ let rec compute_pure_typ (env: pure_env) ?(typ_hint: typ option) (t: trm): typ = Pattern.__ (fun () -> failwith "Unknown representation predicate '%s'" (Ast_to_c.ast_to_string repr)) ]; typ_hprop - | Trm_var xf, [ptr; alloc_cells] when var_eq xf var_free -> + | Trm_var xf, [ptr; alloc_cells] when var_eq xf var_free || var_eq xf var_auto_free -> let ptr_typ = compute_pure_typ env ptr in let alloc_cells_typ = compute_pure_typ env alloc_cells in assert (is_typ_ptr ptr_typ); @@ -1191,23 +1191,34 @@ let handle_resource_errors (t: trm) (phase:resource_error_phase) (exn: exn) = let empty_usage_map = Var_map.empty let delete_stack_allocs instrs res = - let extract_let_mut ti = + let extract_let ti = match trm_let_inv ti with - | Some (x, _, t) -> + | Some (x, _, t) -> [x] + (* DEPRECATED: begin match trm_ref_any_inv t with (* TODO: Stack allocations (i.e. automatic free) for other types of cells (#26) *) | Some ty -> [formula_uninit_cells_var ~mem_typ:mem_typ_any ty x] | None -> [] - end + end *) | None -> [] in - let to_free = List.concat_map extract_let_mut instrs in + let may_be_freed = List.concat_map extract_let instrs in + let may_be_freed = Var_set.of_list may_be_freed in (*Tools.debug "Trying to free %s from %s\n" (String.concat ", " to_free) (resources_to_string (Some res));*) - let res_to_free = Resource_set.make ~linear:(List.map (fun f -> (new_anon_hyp (), f)) to_free) () in + let res_to_extract = List.concat_map + (fun (x, f) -> + begin match Resource_formula.formula_auto_free_inv f with + | Some (base_ptr, cells) when Var_set.mem base_ptr may_be_freed -> + [(new_anon_hyp (), cells); (new_anon_hyp (), f)] + | _ -> [] + end + ) + res.linear + in + let res_to_free = Resource_set.make ~linear:res_to_extract () in let _, removed_res, linear = extract_resources ~split_frac:false res res_to_free in (removed_res, linear) - let check_pure_resource_types ~(pure_ctx: pure_env) (pure_res: pure_resource_set): pure_env = List.fold_left (fun pure_ctx (pure_var, typ) -> let sort = compute_pure_typ pure_ctx typ in @@ -1241,8 +1252,9 @@ let check_fun_contract_types ~(pure_ctx: pure_env) (contract: fun_contract): uni If [magic] is true, fM is not checked (works on any kind of Cell). *) let sync_simplification ?(magic = false) (res: resource_set): resource_set = let find_mem_fn_proof (mem_fn: trm) (mem: trm) = - let proof_type = (trm_apps mem_fn [mem]) in - List.find_opt (fun (_,r) -> Trm_unify.are_same_trm proof_type r) res.pure in + let proof_type = trm_apps mem_fn [mem] in + List.find_opt (fun (_,r) -> Trm_unify.are_same_trm proof_type r) res.pure + in let rec simplify (mem_fn: trm) (t: trm) = Pattern.pattern_match t [ Pattern.(formula_group !__ !__ !__) (fun idx range sub () -> formula_group idx range (simplify mem_fn sub)); @@ -1254,7 +1266,8 @@ let sync_simplification ?(magic = false) (res: resource_set): resource_set = | Some _ -> t | None -> formula_sync mem_fn t ); - Pattern.__ (fun () -> t) + Pattern.__ (fun () -> + if magic then t else formula_sync mem_fn t) ] in let simplify_if_sync (t: trm) = match (formula_sync_inv t) with | Some (mem_fn, t) -> simplify mem_fn t @@ -1437,7 +1450,7 @@ let find_prim_spec typ prim struct_fields : typ * fun_spec_resource = [init_var, typ], [typ], [init_var], formula_cells_var ~mem_typ:mem_typ_any typ var_result (trm_var init_var) in let post_linear = match prim with - | Prim_ref | Prim_ref_uninit -> [new_anon_hyp (), alloc_res] + | Prim_ref | Prim_ref_uninit -> [new_anon_hyp (), alloc_res; new_anon_hyp (), formula_auto_free var_result (formula_uninit alloc_res)] | _ -> [new_anon_hyp (), alloc_res; new_anon_hyp (), formula_free var_result (formula_uninit alloc_res)] in let contract = { diff --git a/lib/framework/resources/resource_formula.ml b/lib/framework/resources/resource_formula.ml index 2a65c9486..acdf31651 100644 --- a/lib/framework/resources/resource_formula.ml +++ b/lib/framework/resources/resource_formula.ml @@ -269,6 +269,19 @@ let var_free = toplevel_var "Free" let formula_free (base_ptr: var) (cells: formula) : formula = trm_apps ~annot:formula_annot (trm_var var_free) [trm_var base_ptr; cells] +let var_auto_free = toplevel_var "AutoFree" +let trm_auto_free = trm_var var_auto_free + +let formula_auto_free (base_ptr: var) (cells: formula) : formula = + trm_apps ~annot:formula_annot (trm_var var_auto_free) [trm_var base_ptr; cells] + +let formula_auto_free_inv (f: formula) : (var * formula) option = + Pattern.pattern_match_opt f [ + Pattern.(trm_apps2 (trm_specific_var var_auto_free) (trm_var !__) !__) (fun base_ptr cells () -> + (base_ptr, cells) + ); + ] + let var_range = toplevel_var "range" let trm_range = trm_var var_range let formula_range (start: trm) (stop: trm) (step: trm) = diff --git a/lib/framework/resources/resource_trm.ml b/lib/framework/resources/resource_trm.ml index d6436bb28..802dec4de 100644 --- a/lib/framework/resources/resource_trm.ml +++ b/lib/framework/resources/resource_trm.ml @@ -217,6 +217,11 @@ let ghost_in_range_extend x r1 r2 = (* let var_ghost_subrange_to_group_in_range = toplevel_var "subrange_to_group_in_range" *) +let var_ghost_unwrap_singleton_desyncgroup = toplevel_var "unwrap_singleton_desyncgroup" + +let ghost_unwrap_singleton_desyncgroup ?(formula : formula option) () = + ghost (ghost_call_opt_args var_ghost_unwrap_singleton_desyncgroup ["H", formula]) + let var_arbitrary = toplevel_var "arbitrary" let var_admit = toplevel_var "admit" diff --git a/lib/transfo/gpu.ml b/lib/transfo/gpu.ml index 2cf963ac6..877188968 100644 --- a/lib/transfo/gpu.ml +++ b/lib/transfo/gpu.ml @@ -86,3 +86,22 @@ let%transfo convert_to_shared_mem ~(chop_dims: int) (tg: target): unit = Gpu_basic.convert_memory (Gpu_basic.smem_alias_spec alias) tg; ) !aliases; ))) tg + +(** [convert_to_register_mem ~chop_dims tg] convert the targeted declaration to register memory, replacing all operations on that variable with the appropriate ones. + [chop_dims]: number of dimensions that will become distributed, that should be chopped off. *) +let%transfo convert_to_register_mem ~(chop_dims: int) (tg: target): unit = + Target.iter (fun p -> + let _,tg_seq_p = Path.index_in_seq p in + let tg = [cPath p] in + Marks.with_marks (fun next_m -> + Resources.with_non_strict_loop_contracts [cPath tg_seq_p] (fun () -> + let alloc_mark = next_m () in + let free_mark = next_m () in + Gpu_basic.convert_memory (Gpu_basic.treg_mem_spec ~alloc_mark ~free_mark chop_dims) tg; + let aliases = ref Var_set.empty in + let kernel_seq = [tSpan [cMark alloc_mark] [cMark free_mark]] in + Gpu_basic.fix_distrib_accesses ~aliases chop_dims kernel_seq tg; + Var_set.iter (fun alias -> + Gpu_basic.convert_memory (Gpu_basic.treg_mem_alias_spec alias) tg; + ) !aliases; + ))) tg diff --git a/lib/transfo/gpu_basic.ml b/lib/transfo/gpu_basic.ml index 1530fff6b..f24f56183 100644 --- a/lib/transfo/gpu_basic.ml +++ b/lib/transfo/gpu_basic.ml @@ -228,6 +228,8 @@ let convert_memory (spec: 'a memory_spec) (alloc_tg: target): unit = converted to shared memory, and there are 2 dimensions of blocks, then there are now 2 distributed dimensions. This function would convert all instances of MINDEX4(...) on that variable to MINDEX3(DMINDEX2(...), ...). *) let fix_distrib_accesses ~(aliases: Var_set.t ref) (chop_dims: int) (body_span_tg: target) (alloc_tg: target): unit = + if chop_dims = 0 then () else begin + let body_seq_path,body_seq_span = Target.resolve_target_span_exactly_one body_span_tg in let _ = Target.resolve_target_exactly_one alloc_tg in (* expect only one target *) let open Resource_formula in @@ -235,7 +237,7 @@ let fix_distrib_accesses ~(aliases: Var_set.t ref) (chop_dims: int) (body_span_t let error = "Gpu_basic.ml: expected target to point to a matrix allocation" in let var, _, _ = trm_inv ~error trm_let_inv alloc_trm in - let rec aux ?(alias_binder:var option) loop_depth t = match (Matrix_trm.access_inv t) with + let rec aux ?(alias_binder:var option) threadfor_depth t = match (Matrix_trm.access_inv t) with | Some ({desc = Trm_var base}, dims, inds) when (var_eq var base) -> (match alias_binder with | Some v -> aliases := Var_set.add v !aliases; @@ -246,26 +248,33 @@ let fix_distrib_accesses ~(aliases: Var_set.t ref) (chop_dims: int) (body_span_t ((Matrix_trm.dmindex distrib_dims distrib_inds) :: real_inds)) | _ -> Pattern.pattern_match t [ - Pattern.(trm_let !__ __ __ ) (fun v () -> trm_map (aux ~alias_binder:v loop_depth) t); - Pattern.(trm_for __ __ __ __) (fun () -> trm_map (aux (loop_depth + 1)) t); + Pattern.(trm_let !__ __ __ ) (fun v () -> trm_map (aux ~alias_binder:v threadfor_depth) t); + Pattern.(trm_for __ !__ __ __) (fun mode () -> + let threadfor_depth = begin match mode with + | GpuThread | MagicThread -> threadfor_depth + 1 + | _ -> threadfor_depth + end in + trm_map (aux threadfor_depth) t + ); (* LATER: better heuristics to convert the desyncgroups if ghosts are being used on these dimensions *) Pattern.(formula_group !__ !(formula_range __ !__ __) !__) (fun ind range stop body () -> Pattern.when_ (is_free_var_in_trm var t); - let body = aux (loop_depth + 1) body in - if (chop_dims - loop_depth <= 0) then + let body = aux (threadfor_depth + 1) body in + if (chop_dims - threadfor_depth <= 0) then formula_group ind range body else formula_desyncgroup ind stop body ); Pattern.(formula_desyncgroup !__ !__ !__) (fun ind stop body () -> - formula_desyncgroup ind stop (aux (loop_depth + 1) body) + formula_desyncgroup ind stop (aux (threadfor_depth + 1) body) ); - Pattern.__ (fun () -> trm_map (aux loop_depth) t) + Pattern.__ (fun () -> trm_map (aux threadfor_depth) t) ] in Target.apply_at_path (fun body_seq -> update_span_helper body_seq_span body_seq (fun instrs -> Mlist.to_list (Mlist.map (fun instr -> Trm (aux 0 instr)) instrs)) ) body_seq_path) alloc_tg + end (** [desync_alloc_ghosts] inserts the rewriting ghosts needed to take the flattened DesyncGroup of all distributed dimensions, which is produced by smem_alloc, treg_alloc, etc. into a nest of DesyncGroups, which can be used in a `thread for`. *) @@ -290,6 +299,10 @@ let desync_alloc_ghosts (inverse: bool) (distrib_dims: trm list) (real_dims: trm trm_apps ~annot:formula_annot trm_desyncgroup [dim; formula_fun [idx, typ_int] formula]) distrib_inds distrib_dims inside_formula in + match distrib_dims with + | [] -> [] + | _ -> begin + let from, into = if inverse then ((mul_nest distrib_dims),(Matrix_trm.msize distrib_dims)) else @@ -346,6 +359,7 @@ let desync_alloc_ghosts (inverse: bool) (distrib_dims: trm list) (real_dims: trm let ghosts = msize_rewrite :: ghosts in let ghosts = if inverse then (List.rev ghosts) else ghosts in msize_assume :: ghosts + end (* Global memory specification *) let gmem_spec : unit memory_spec = { @@ -419,6 +433,43 @@ let smem_alias_spec (alias_var: var): unit memory_spec = { extra_patterns = (fun (var,_) aux -> []); } +(* Thread register memory specification *) +let treg_mem_spec ?(alloc_mark="") ?(free_mark="") (chop_dims: int): (trm list * trm list) memory_spec = { + alloc_handler = (fun alloc_trm -> ( + let error = "Gpu.convert_to_register_mem: expected target to point to a matrix allocation" in + let (array_var, typ_array, typ_alloc, trms, init) = trm_inv ~error (Matrix_trm.let_alloc_inv) alloc_trm in + assert (not init); (* LATER: implement CALLOC *) + let distrib_dims, real_dims = List.split_at chop_dims trms in + let ref_uninit = if chop_dims = 0 then var__treg_ref_uninit_s else var__treg_ref_uninit in + let f = trm_add_cstyle (Typ_arguments [typ_alloc]) (trm_var (ref_uninit (List.length real_dims))) in + let alloc_instr = trm_apps f real_dims ~ghost_args:[(new_var "T", typ_alloc)] in + let instrs = Mlist.of_list ( + (trm_let (array_var,typ_array) alloc_instr) :: + (desync_alloc_ghosts false distrib_dims real_dims array_var (trm_var var_treg)) + ) in + let t = trm_seq_nobrace (Mlist.insert_mark_at (Mlist.length instrs) alloc_mark instrs) in + t, (distrib_dims,real_dims), array_var + )); + get_handler = (fun _ args -> trm_apps (trm_var var__treg_get) args); + set_handler = (fun _ args -> trm_apps (trm_var var__treg_set) args); + free_handler = (fun _ (var, (distrib_dims, real_dims)) args -> + let instrs = (Mlist.of_list + (desync_alloc_ghosts true distrib_dims real_dims var (trm_var var_treg))) in + trm_seq_nobrace (Mlist.insert_mark_at 0 free_mark instrs) + ); + cell_var = var_treg; + extra_patterns = (fun (var,_) aux -> []); +} + +let treg_mem_alias_spec (alias_var: var): unit memory_spec = { + alloc_handler = (fun t -> (t,(),alias_var)); + get_handler = (fun _ args -> trm_apps (trm_var var__treg_get) args); + set_handler = (fun _ args -> trm_apps (trm_var var__treg_set) args); + free_handler = (fun t _ _ -> t); + cell_var = var_treg; + extra_patterns = (fun (var,_) aux -> []); +} + (* ----------------------- Barrier conversion ------------------------ *) (** [remove_loop_around_barrier] simplifies the pattern From cc16ffacfdaa5c8829bef5cfefe59a97a06883e3 Mon Sep 17 00:00:00 2001 From: Thomas Koehler Date: Mon, 6 Jul 2026 17:44:58 +0200 Subject: [PATCH 04/23] fix desync group coercion; weaken some dealloc logic to desync groups; allow hoisting instructions downwards; generate first typechecked CUDA code for matmul --- case_studies/gpu/matmul/matmul.cpp | 7 ++ case_studies/gpu/matmul/matmul.ml | 73 ++++++++++++++++--- include/optitrust_gpu.h | 30 +++++--- lib/ast/pattern.ml | 6 ++ .../resources/resource_computation.ml | 24 ++++-- lib/framework/target/constr.ml | 6 +- lib/framework/target/path.ml | 5 ++ lib/framework/target/target.ml | 6 +- lib/transfo/gpu_basic.ml | 50 ++++++++++--- lib/transfo/loop.ml | 73 +++++++++++++++---- tests/loop/hoist_instr/loop_hoist_instr.cpp | 25 +++++++ tests/loop/hoist_instr/loop_hoist_instr.ml | 10 +++ .../loop/hoist_instr/loop_hoist_instr_exp.cpp | 72 ++++++++++++++++++ 13 files changed, 330 insertions(+), 57 deletions(-) create mode 100644 tests/loop/hoist_instr/loop_hoist_instr.cpp create mode 100644 tests/loop/hoist_instr/loop_hoist_instr.ml create mode 100644 tests/loop/hoist_instr/loop_hoist_instr_exp.cpp diff --git a/case_studies/gpu/matmul/matmul.cpp b/case_studies/gpu/matmul/matmul.cpp index f7d072f56..627cd5ca7 100644 --- a/case_studies/gpu/matmul/matmul.cpp +++ b/case_studies/gpu/matmul/matmul.cpp @@ -6,6 +6,8 @@ __ghost(to_prove, "MSIZE2(exact_div(32, 8), exact_div(32, 4)) = MSIZE2(4, 8)"); __ghost(to_prove, "MSIZE2(4, 8) = MSIZE2(8, 4)"); __ghost(to_prove, "MSIZE2(8, 4) = MSIZE2(4, 8)"); __ghost(to_prove, "MSIZE2(4, 8) = MSIZE2(exact_div(32, 8), exact_div(32, 4))"); +__ghost(to_prove, "MSIZE2(8, 4) = MSIZE2(exact_div(32, 8), exact_div(32, 4))"); +__ghost(to_prove, "MSIZE2(exact_div(32, 8), exact_div(32, 4)) = MSIZE2(8, 4)"); // ---- __DECL(reduce_sum, "int * (int -> float) -> float"); @@ -24,6 +26,11 @@ void mm(float* c, float* a, float* b, int m, int n, int p) { __writes("c ~> Matrix2(m, n, matmul(A, B, p))"); __preserves("HostCtx"); + // FIXME: + __ghost(to_prove, "exact_div(m, 32) >= 0"); + __ghost(to_prove, "exact_div(n, 32) >= 0"); + // ---- + for (int i = 0; i < m; i++) { __xwrites("for j in 0..n -> &c[MINDEX2(m, n, i, j)] ~~> matmul(A, B, p)(i, j)"); diff --git a/case_studies/gpu/matmul/matmul.ml b/case_studies/gpu/matmul/matmul.ml index 706c75dbb..3c2dfc55c 100644 --- a/case_studies/gpu/matmul/matmul.ml +++ b/case_studies/gpu/matmul/matmul.ml @@ -5,10 +5,10 @@ let _ = Flags.check_validity := true (* FIXME: this flag behaviour needs to be c let _ = Flags.pretty_matrix_notation := false let _ = Flags.recompute_resources_between_steps := false let _ = Flags.disable_stringreprs := true -let _ = Flags.save_ast_for_steps := Some Flags.Steps_script +let _ = Flags.save_ast_for_steps := Some Steps_important (* Flags.Steps_script *) (* let _ = Flags.report_exectime := true *) -let stage_ok = fun i -> i = 6 +let stage_ok = fun i -> i >= 7 let bm = 32 let bn = 32 @@ -70,6 +70,33 @@ let _ = Run.script_cpp_stage stage_ok (fun () -> *) ) +let _ = Run.script_cpp_stage stage_ok (fun () -> + (* move some annoying ghosts away for later transformations *) + + (* TODO: + - enable hoist span and add unit test for it + - infer ~down:true from destination + - see if two-step hoists can be merged into a single one + *) + !! Sequence.intro ~mark:"s1" + ~start:[tFirst; occFirst; cForBody ~body:[cWrite ~lhs:[cVar "sum"] ()] "ti"] + ~stop:[tBefore; occFirst; cFor ~body:[cWrite ~lhs:[cVar "sum"] ()] "tj"] (); + !! Sequence.intro ~mark:"s2" + ~start:[tAfter; cFor ~body:[cWrite ~lhs:[cVar "c_gmem"] ()] "tj"] + ~stop:[tLast; cForBody ~body:[cWrite ~lhs:[cVar "c_gmem"] ()] "ti"] (); + !! Loop.hoist_instr ~dest:[tBefore; cFor ~body:[cWrite ~lhs:[cVar "c_gmem"] ()] "bj"] [cMark "s1"]; + !! Loop.hoist_instr ~down:true ~dest:[tAfter; cFor ~body:[cWrite ~lhs:[cVar "c_gmem"] ()] "bj"] [cMark "s2"]; + + !! Sequence.intro ~mark:"s3" + ~start:[occFirst; cForBody ~body:[cWrite ~lhs:[cVar "sum"] ()] "bi"; dBefore 1] + ~stop:[tBefore; occFirst; cFor ~body:[cWrite ~lhs:[cVar "sum"] ()] "bj"] (); + !! Sequence.intro ~mark:"s4" + ~start:[tAfter; cFor ~body:[cWrite ~lhs:[cVar "c_gmem"] ()] "bj"] + ~stop:[tLast; cForBody ~body:[cWrite ~lhs:[cVar "c_gmem"] ()] "bi"] (); + !! Loop.hoist_instr ~dest:[tBefore; cFor ~body:[cWrite ~lhs:[cVar "c_gmem"] ()] "bi"] [cMark "s3"]; + !! Loop.hoist_instr ~down:true ~dest:[tAfter; cFor ~body:[cWrite ~lhs:[cVar "c_gmem"] ()] "bi"] [cMark "s4"]; +) + let _ = Flags.check_validity := false let _ = Run.script_cpp_stage stage_ok (fun () -> @@ -93,7 +120,7 @@ let _ = Run.script_cpp_stage stage_ok (fun () -> (* Wrap kernel body in launch and kill calls *) !! Gpu.create_kernel_launch bpg tpb smem_szs - ~setup_end:[tBefore; cFor "bi"] ~teardown_begin:[tAfter; cFor "bi"] + ~setup_end:[tBefore; cFor ~body:[cWrite ~lhs:[cVar "sum"] ()] "bi"] ~teardown_begin:[tAfter; cFor ~body:[cWrite ~lhs:[cVar "sum"] ()] "bi"] [tBefore; cVarDef "a_smem"] [tAfter; cPrimCall Prim_delete ~args:[[cVar "a_smem"]]]; !! Gpu.convert_tail_thread_for [1] [occFirst; cFor "ti"; cFor ~body:[cWrite ~lhs:[cVar "sum"] ()] "tj"]; @@ -104,7 +131,7 @@ let _ = Run.script_cpp_stage stage_ok (fun () -> let _ = Run.script_cpp_stage stage_ok (fun () -> !! Gpu.convert_tail_thread_for [1] [cFor "ti"; cFor ~body:[cPlusEq ~lhs:[cVar "sum"] ()] "tj"]; (* occLast; cWrite *) !! Gpu.convert_tail_thread_for [1] [cFor "ti"; cFor ~body:[cWrite ~lhs:[cVar "c_gmem"] ()] "tj"]; - !! Gpu.convert_tail_thread_for [1] [cFor "bi"; cFor "bj"]; + !! Gpu.convert_tail_thread_for [1] [cFor "bi"; cFor ~body:[cPlusEq ~lhs:[cVar "sum"] ()] "bj"]; ) let _ = Run.script_cpp_stage stage_ok (fun () -> @@ -128,7 +155,7 @@ let _ = Run.script_cpp_stage stage_ok (fun () -> (Matrix_trm.msize [(trm_int 4); (trm_int 8)]) (Matrix_trm.msize [(trm_exact_div_int (trm_int 32) (trm_int 8)); (trm_exact_div_int (trm_int 32) (trm_int 4))]) - [tLast; cForBody "bj"]; + [tLast; cForBody ~body:[cPlusEq ~lhs:[cVar "sum"] ()] "bj"]; ) [nbAny; cFunBody "mm"; cFor ""]; !! Gpu.convert_to_global_mem [nbMulti; cVarDefs ["a_gmem"; "b_gmem"; "c_gmem"]]; @@ -136,16 +163,42 @@ let _ = Run.script_cpp_stage stage_ok (fun () -> !! Gpu.convert_to_register_mem ~chop_dims:2 [cVarDef "sum"]; !! Gpu.convert_to_register_mem ~chop_dims:0 [nbMulti; cVarDefs ["a_regs"; "b_regs"]]; + (* NOTE: 3/5 first groups of c_gmem don't need to be sync during core computation : bj ti tj *) + !! Gpu.to_desync_for [nbMulti; cFor ~body:[cVarDef "sum"] "bi"; cCall ~args:[[cTrue]; [cFun ~body:[cFun ~body:[cFun ~body:[cVar "c_gmem"] ()] ()] ()]] "Group"]; +(* ) + +WEIRD print/parse bug here + +Fatal error: exception Failure("File /home/thomas/code/optitrust/case_studies/gpu/matmul/matmul_stg6.cpp, line 264, columns 161-195: Arithmetic operand has a non standard type (Trm_var(float))") + +let _ = Run.script_cpp_stage stage_ok (fun () -> +*) let kernel_mark = "kernel_body" in !! Marks.add_fake_instr kernel_mark [tAfter; cCall "kernel_launch"]; !! Instr.delete [occFirst; cCall "magic_barrier"]; !! Instr.delete [occFirst; cCall "magic_barrier"]; - (* FIXME: !! Instr.delete [occIndex 1; cCall "magic_barrier"]; *) - !! Gpu.magic_barrier_to_blocksync [cMark kernel_mark] [nbMulti; cFor "bkIdx"; cCall "magic_barrier"]; - (* TODO: barrier option 2 - !! Gpu.insert_barrier [tFirst; cForBody "bkIdx"]; *) - !! Instr.move ~dest:[tAfter; cCall "kernel_teardown_begin"] [cCall "magic_barrier"]; + !! Gpu.magic_barrier_to_blocksync ~mark:"sync1" [cMark kernel_mark] [occFirst; cFor "bkIdx"; cCall "magic_barrier"]; + !! Gpu.insert_threadsctx_rewrite + (Matrix_trm.msize [(trm_int 8); (trm_int 4)]) + (Matrix_trm.msize [(trm_exact_div_int (trm_int 32) (trm_int 8)); + (trm_exact_div_int (trm_int 32) (trm_int 4))]) + [tBefore; cMark "sync1"]; + !! Gpu.insert_threadsctx_rewrite + (Matrix_trm.msize [(trm_exact_div_int (trm_int 32) (trm_int 8)); + (trm_exact_div_int (trm_int 32) (trm_int 4))]) + (Matrix_trm.msize [(trm_int 8); (trm_int 4)]) + [tAfter; cMark "sync1"]; + + !! Instr.delete [occFirst; cFor "bkIdx"; cCall "magic_barrier"]; + (* FIXME: shouldn't be possible to delete barrier above, should be blocksync as well, nbMulti *) + (* LATER: barrier option 2 + !! Gpu.insert_barrier [tFirst; cForBody "bkIdx"]; *) + !! Instr.delete [occFirst; cCall "magic_barrier"]; + !! Instr.move ~dest:[tBefore; cCall "magic_barrier"] [cCall "kernel_teardown_begin"]; !! Gpu.magic_barrier_to_teardown_sync [cCall "magic_barrier"]; + + !! Resources.ensure_computed (); + !! Trace.generate_cuda ~check_expected:true (); ) diff --git a/include/optitrust_gpu.h b/include/optitrust_gpu.h index 00468d16b..7e04607df 100644 --- a/include/optitrust_gpu.h +++ b/include/optitrust_gpu.h @@ -126,6 +126,17 @@ __GHOST(kernel_teardown_sync) { __admitted(); } +__DECL(treg_sync_mem, "MemType -> Prop"); +__AXIOM(treg_treg_sync_mem, "treg_sync_mem(TReg)"); + +__GHOST(treg_sync) { + __requires("t: int, H: HProp"); + __reads("ThreadsCtx(t ..+ MSIZE0())"); + __consumes("H"); + __produces("Sync(treg_sync_mem, H)"); + __admitted(); +} + /* --- Memory management ---- */ // To appease C++ typechecker @@ -242,7 +253,7 @@ template T* __smem_malloc1(int N1) { // LATER: matrix sugar for this __produces("desync_for i in ..bpg -> for j1 in 0..N1 -> &_Res[MINDEX2(bpg, N1, DMINDEX1(bpg, i), j1)] ~> UninitCellOf(SMem)"); // expect a permission of groups, not desyncgroups. Should sync (end kernel) first before freeing. - __produces("Free(_Res, for i in 0..bpg -> for j1 in 0..N1 -> &_Res[MINDEX2(bpg, N1, DMINDEX1(bpg, i), j1)] ~> UninitCellOf(SMem))"); + __produces("Free(_Res, desync_for i in ..bpg -> for j1 in 0..N1 -> &_Res[MINDEX2(bpg, N1, DMINDEX1(bpg, i), j1)] ~> UninitCellOf(SMem))"); __consumes("SMemToken(sizeof(T)*N1)"); __ensures("__spec_override_ret_implicit(ptr(T))"); __admitted(); @@ -255,7 +266,7 @@ template T* __smem_malloc2(int N1, int N2) { __preserves("KernelSetupCtx"); __reads("KernelParams(bpg,tpb,smem_sz)"); __produces("desync_for i in ..bpg -> for j1 in 0..N1 -> for j2 in 0..N2 -> &_Res[MINDEX3(bpg, N1, N2, DMINDEX1(bpg, i), j1, j2)] ~> UninitCellOf(SMem)"); - __produces("Free(_Res, for i in 0..bpg -> for j1 in 0..N1 -> for j2 in 0..N2 -> &_Res[MINDEX3(bpg, N1, N2, DMINDEX1(bpg, i), j1, j2)] ~> UninitCellOf(SMem))"); + __produces("Free(_Res, desync_for i in ..bpg -> for j1 in 0..N1 -> for j2 in 0..N2 -> &_Res[MINDEX3(bpg, N1, N2, DMINDEX1(bpg, i), j1, j2)] ~> UninitCellOf(SMem))"); __consumes("SMemToken(sizeof(T)*(N1*N2))"); __ensures("__spec_override_ret_implicit(ptr(T))"); __admitted(); @@ -268,7 +279,7 @@ template T* __smem_malloc3(int N1, int N2, int N3) { __preserves("KernelSetupCtx"); __reads("KernelParams(bpg,tpb,smem_sz)"); __produces("desync_for i in ..bpg -> for j1 in 0..N1 -> for j2 in 0..N2 -> for j3 in 0..N3 -> &_Res[MINDEX4(bpg, N1, N2, N3, DMINDEX1(bpg, i), j1, j2, j3)] ~> UninitCellOf(SMem)"); - __produces("Free(_Res, for i in 0..bpg -> for j1 in 0..N1 -> for j2 in 0..N2 -> for j3 in 0..N3 -> &_Res[MINDEX4(bpg, N1, N2, N3, DMINDEX1(bpg, i), j1, j2, j3)] ~> UninitCellOf(SMem))"); + __produces("Free(_Res, desync_for i in ..bpg -> for j1 in 0..N1 -> for j2 in 0..N2 -> for j3 in 0..N3 -> &_Res[MINDEX4(bpg, N1, N2, N3, DMINDEX1(bpg, i), j1, j2, j3)] ~> UninitCellOf(SMem))"); __consumes("SMemToken(sizeof(T)*(N1*N2*N3))"); __ensures("__spec_override_ret_implicit(ptr(T))"); __admitted(); @@ -282,8 +293,8 @@ template void __smem_free1(T* p, int N1) { __requires("tpb: int, bpg: int, smem_sz: int"); __preserves("KernelTeardownCtx"); __reads("KernelParams(bpg,tpb,smem_sz)"); - __consumes("for i in 0..bpg -> for j1 in 0..N1 -> &p[MINDEX2(bpg, N1, DMINDEX1(bpg, i), j1)] ~> UninitCellOf(SMem)"); - __consumes("Free(p, for i in 0..bpg -> for j1 in 0..N1 -> &p[MINDEX2(bpg, N1, DMINDEX1(bpg, i), j1)] ~> UninitCellOf(SMem))"); + __consumes("desync_for i in ..bpg -> for j1 in 0..N1 -> &p[MINDEX2(bpg, N1, DMINDEX1(bpg, i), j1)] ~> UninitCellOf(SMem)"); + __consumes("Free(p, desync_for i in ..bpg -> for j1 in 0..N1 -> &p[MINDEX2(bpg, N1, DMINDEX1(bpg, i), j1)] ~> UninitCellOf(SMem))"); __produces("SMemToken(sizeof(T)*N1)"); __ensures("__spec_override_noret()"); __admitted(); @@ -293,8 +304,8 @@ template void __smem_free2(T* p, int N1, int N2) { __requires("tpb: int, bpg: int, smem_sz: int"); __preserves("KernelTeardownCtx"); __reads("KernelParams(bpg,tpb,smem_sz)"); - __consumes("for i in 0..bpg -> for j1 in 0..N1 -> for j2 in 0..N2 -> &p[MINDEX3(bpg, N1, N2, DMINDEX1(bpg, i), j1, j2)] ~> UninitCellOf(SMem)"); - __consumes("Free(p, for i in 0..bpg -> for j1 in 0..N1 -> for j2 in 0..N2 -> &p[MINDEX3(bpg, N1, N2, DMINDEX1(bpg, i), j1, j2)] ~> UninitCellOf(SMem))"); + __consumes("desync_for i in ..bpg -> for j1 in 0..N1 -> for j2 in 0..N2 -> &p[MINDEX3(bpg, N1, N2, DMINDEX1(bpg, i), j1, j2)] ~> UninitCellOf(SMem)"); + __consumes("Free(p, desync_for i in ..bpg -> for j1 in 0..N1 -> for j2 in 0..N2 -> &p[MINDEX3(bpg, N1, N2, DMINDEX1(bpg, i), j1, j2)] ~> UninitCellOf(SMem))"); __produces("SMemToken(sizeof(T)*(N1*N2))"); __ensures("__spec_override_noret()"); __admitted(); @@ -304,8 +315,8 @@ template void __smem_free3(T* p, int N1, int N2, int N3) { __requires("tpb: int, bpg: int, smem_sz: int"); __preserves("KernelTeardownCtx"); __reads("KernelParams(bpg,tpb,smem_sz)"); - __consumes("for i in 0..bpg -> for j1 in 0..N1 -> for j2 in 0..N2 -> for j3 in 0..N3 -> &p[MINDEX4(bpg, N1, N2, N3, DMINDEX1(bpg, i), j1, j2, j3)] ~> UninitCellOf(SMem)"); - __consumes("Free(p, for i in 0..bpg -> for j1 in 0..N1 -> for j2 in 0..N2 -> for j3 in 0..N3 -> &p[MINDEX4(bpg, N1, N2, N3, DMINDEX1(bpg, i), j1, j2, j3)] ~> UninitCellOf(SMem))"); + __consumes("desync_for i in ..bpg -> for j1 in 0..N1 -> for j2 in 0..N2 -> for j3 in 0..N3 -> &p[MINDEX4(bpg, N1, N2, N3, DMINDEX1(bpg, i), j1, j2, j3)] ~> UninitCellOf(SMem)"); + __consumes("Free(p, desync_for i in ..bpg -> for j1 in 0..N1 -> for j2 in 0..N2 -> for j3 in 0..N3 -> &p[MINDEX4(bpg, N1, N2, N3, DMINDEX1(bpg, i), j1, j2, j3)] ~> UninitCellOf(SMem))"); __produces("SMemToken(sizeof(T)*(N1*N2*N3))"); __ensures("__spec_override_noret()"); __admitted(); @@ -329,6 +340,7 @@ template T* __treg_ref_s(T v) { __requires("t: int"); __preserves("ThreadsCtx(t..+MSIZE0())"); __produces("_Res ~~>[TReg] v"); + __produces("AutoFree(_Res, _Res ~> UninitCellOf(TReg))"); __ensures("__spec_override_ret_implicit(ptr(T))"); // admitted for now because proper autofree/typechecking for TReg is not implemented __admitted(); diff --git a/lib/ast/pattern.ml b/lib/ast/pattern.ml index 83fce73cd..ebab90879 100644 --- a/lib/ast/pattern.ml +++ b/lib/ast/pattern.ml @@ -85,6 +85,12 @@ let (^::) (fh: 'a -> 't -> 'b) (ft: 'b -> 't list -> 'c) (k: 'a) (l: 't list): ' k | _ -> raise Next +let (^*) f_fst f_snd k t = + let (p, q) = t in + let k = f_fst k p in + let k = f_snd k q in + k + let trm_apps0 fn = trm_apps fn nil __ __ let trm_apps1 fn arg1 = trm_apps fn (arg1 ^:: nil) __ __ let trm_apps2 fn arg1 arg2 = trm_apps fn (arg1 ^:: arg2 ^:: nil) __ __ diff --git a/lib/framework/resources/resource_computation.ml b/lib/framework/resources/resource_computation.ml index c6fe09589..151e4c682 100644 --- a/lib/framework/resources/resource_computation.ml +++ b/lib/framework/resources/resource_computation.ml @@ -467,11 +467,15 @@ let subtract_linear_resource_item ~(split_frac: bool) ((x, formula): resource_it (* DesyncGroup coercion *) (* TODO: does this need to change the formula instantiation? "Formula_inst.inst_forget_group?" how would it combine with Uninit? *) - let desyncgroup_coerce formula_candidate = - Pattern.pattern_match formula_candidate [ - Pattern.(formula_group !__ (formula_range (trm_int (eq 0)) !__ (trm_int (eq 1))) !__) - (fun idx dim inner_formula () -> - formula_desyncgroup idx dim inner_formula + let rec may_coerce_desyncgroup formula_candidate formula = + Pattern.pattern_match (formula, formula_candidate) [ + Pattern.((formula_desyncgroup __ __ !__) ^* (formula_group !__ (formula_range (trm_int (eq 0)) !__ (trm_int (eq 1))) !__)) + (fun inner_formula idx dim inner_formula_candidate () -> + formula_desyncgroup idx dim (may_coerce_desyncgroup inner_formula_candidate inner_formula) + ); + Pattern.((formula_desyncgroup __ __ !__) ^* (formula_desyncgroup !__ !__ !__)) + (fun inner_formula idx dim inner_formula_candidate () -> + formula_desyncgroup idx dim (may_coerce_desyncgroup inner_formula_candidate inner_formula) ); Pattern.__ (fun () -> formula_candidate) ] in @@ -501,14 +505,12 @@ let subtract_linear_resource_item ~(split_frac: bool) ((x, formula): resource_it (* Used by {!subtract_linear_resource_item} in the case where [formula] is not a read-only resource. *) (* LATER: Improve the structure of the linear_resource_set to make this function faster on most frequent cases *) - let is_desyncgroup = Option.is_some (formula_desyncgroup_inv formula) in extract (fun (candidate_name, formula_candidate) -> (* (try Printf.printf "ref: (%s) %s\ncandidate: (%s) %s \n\n" (if uninit then "UNINIT" else "INIT") (Ast_to_c.ast_to_string formula) (if (is_formula_uninit formula_candidate) then "UNINIT" else "INIT") (Ast_to_c.ast_to_string formula_candidate) with CannotTransformIntoUninit _ -> ());*) try - - let formula_candidate = if is_desyncgroup then (desyncgroup_coerce formula_candidate) else formula_candidate in + let formula_candidate = may_coerce_desyncgroup formula_candidate formula in let inst_by, formula_to_unify = (* Check for possible Uninit coercion if formula_candidate is not already uninit *) if uninit && not (is_formula_uninit formula_candidate) then ( @@ -1266,6 +1268,12 @@ let sync_simplification ?(magic = false) (res: resource_set): resource_set = | Some _ -> t | None -> formula_sync mem_fn t ); + Pattern.(formula_uninit_cell !__ !__) (fun var mem_typ () -> + if magic then t else + match (find_mem_fn_proof mem_fn mem_typ) with + | Some _ -> t + | None -> formula_sync mem_fn t + ); Pattern.__ (fun () -> if magic then t else formula_sync mem_fn t) ] in diff --git a/lib/framework/target/constr.ml b/lib/framework/target/constr.ml index b0afd9dc8..85cff7b64 100644 --- a/lib/framework/target/constr.ml +++ b/lib/framework/target/constr.ml @@ -461,7 +461,7 @@ let target_to_target_struct ?(default_occ = ExpectNb 1) (tr : target) : target_s in List.iter process_constr tr; let tgs = { - target_path = List.filter (function | Constr_relative _ | Constr_occurrences _ -> false | _ -> true) tr; + target_path = List.filter (function | Constr_relative _ | Constr_occurrences _ | Constr_incontracts -> false | _ -> true) tr; target_relative = begin match !relative with | None -> TargetAt | Some re -> re end; target_occurrences = begin match !occurences with | None -> default_occ | Some oc -> oc end; target_incontracts = !incontracts; @@ -737,7 +737,7 @@ let rec check_constraint ~(incontracts:bool) (c : constr) (t : trm) : bool = check_target p_cond cond && check_target p_step step && check_target p_body body - | Constr_for (p_index, p_mode, p_start, p_direction, p_stop, p_step, p_body), Trm_for(range, mode, body, _) -> + | Constr_for (p_index, p_mode, p_start, p_direction, p_stop, p_step, p_body), Trm_for(range, mode, body, contract) -> let direction_match = match p_direction with | None -> true | Some d -> d = range.direction in @@ -792,7 +792,7 @@ let rec check_constraint ~(incontracts:bool) (c : constr) (t : trm) : bool = check_name name x.name | Constr_lit pred_l, Trm_lit l -> pred_l l - | Constr_fun (cl_args, ty_pred, p_body), Trm_fun (args, tx, body, _) -> + | Constr_fun (cl_args, ty_pred, p_body), Trm_fun (args, tx, body, contract) -> ty_pred tx && check_args cl_args args && check_target p_body body diff --git a/lib/framework/target/path.ml b/lib/framework/target/path.ml index f5ca65eeb..864bdc0e4 100644 --- a/lib/framework/target/path.ml +++ b/lib/framework/target/path.ml @@ -505,6 +505,11 @@ let extract_last_dir_span (p: path) : path * span = if debug_path then Tools.debug "Path: %s" (path_to_string p); path_fail p "Path.extract_last_dir_span expects the last direction to be inside a sequence." +let span_in_surrounding_loop (dl : path) : span * path = + let p, span = extract_last_dir_span dl in + match List.rev p with + | Dir_body :: p' -> (span, List.rev p') + | _ -> path_fail dl "Path.index_in_surrounding_loop: unexpected path" (** [split_common_prefix]: given paths [a] and [b], returns [(p, ra, rb)] such that [a = p @ ra] and [b = p @ rb] *) diff --git a/lib/framework/target/target.ml b/lib/framework/target/target.ml index 509b441e8..dcc863480 100644 --- a/lib/framework/target/target.ml +++ b/lib/framework/target/target.ml @@ -154,7 +154,7 @@ let dAfter (i : int) : constr = (** [dSeqNth]: matches the instruction with index [n] on a sequence. *) let dSeqNth (n : int) : constr = - Constr_dir (Dir_seq_nth n) + Constr_dir (Dir_seq_nth n) (** [dCond]: matches a condition. *) let dCond : constr = @@ -231,7 +231,6 @@ let dEnumConstVal : enum_const_dir = Enum_const_val let dArg (n : int) : constr = Constr_dir (Dir_arg_nth n) - (** [string_to_rexp regexp substr s trmKind]: transforms a string into a regular expression used to match ast nodes based on their code representation. [string_to_rexp] - denotes a flag to tell if the string entered is a regular epxression or no @@ -687,6 +686,9 @@ let cVar ?(regexp : bool = false) ?(substr : bool = false) ?(typ : string = "") if typ = "" && typ_pred == typ_constraint_default then c else (* this line is just an optimization. *) Constr_target (with_type ~typ ~typ_pred [c]) +let cVars (vars : string list) : constr = + cOr (List.map (fun v -> [cVar v]) vars) + let cVarId (var : var) : constr = Constr_pred (fun t -> match trm_var_inv t with diff --git a/lib/transfo/gpu_basic.ml b/lib/transfo/gpu_basic.ml index f24f56183..c0c18272a 100644 --- a/lib/transfo/gpu_basic.ml +++ b/lib/transfo/gpu_basic.ml @@ -224,6 +224,22 @@ let convert_memory (spec: 'a memory_spec) (alloc_tg: target): unit = ) seq ) alloc_tg +(** [to_desync_for] weakens a group into a desync group. *) +let to_desync_for (tg: target): unit = + let open Resource_formula in + Target.iter (fun p -> + Target.apply_at_path (fun t -> + Pattern.pattern_match t [ + Pattern.(formula_group !__ (formula_range __ !__ __) !__) (fun ind stop body () -> + formula_desyncgroup ind stop body + ); + Pattern.(formula_desyncgroup __ __ __) (fun () -> + t (* no-op *) + ); + ] + ) p + ) tg + (** [fix_distrib_accesses] fixes distributed dimensions: e.g. if a 4D buffer declared at the kernel level is converted to shared memory, and there are 2 dimensions of blocks, then there are now 2 distributed dimensions. This function would convert all instances of MINDEX4(...) on that variable to MINDEX3(DMINDEX2(...), ...). *) @@ -256,14 +272,15 @@ let fix_distrib_accesses ~(aliases: Var_set.t ref) (chop_dims: int) (body_span_t end in trm_map (aux threadfor_depth) t ); - (* LATER: better heuristics to convert the desyncgroups if ghosts are being used on these dimensions *) Pattern.(formula_group !__ !(formula_range __ !__ __) !__) (fun ind range stop body () -> Pattern.when_ (is_free_var_in_trm var t); let body = aux (threadfor_depth + 1) body in - if (chop_dims - threadfor_depth <= 0) then - formula_group ind range body - else + (* LATER: better heuristics to convert the desyncgroups if ghosts are being used on these dimensions *) + let probably_distributed = chop_dims - threadfor_depth > 0 in + if probably_distributed then formula_desyncgroup ind stop body + else + formula_group ind range body ); Pattern.(formula_desyncgroup !__ !__ !__) (fun ind stop body () -> formula_desyncgroup ind stop (aux (threadfor_depth + 1) body) @@ -287,15 +304,23 @@ let desync_alloc_ghosts (inverse: bool) (distrib_dims: trm list) (real_dims: trm Matrix_trm.access (trm_var matrix) (distrib_dim :: real_dims) (distrib_ind :: (List.map trm_var real_inds)) ) in List.fold_right2 (fun idx dim formula -> - trm_apps ~annot:formula_annot trm_group [formula_range (trm_int 0) dim (trm_int 1); formula_fun [idx, typ_int] formula]) + (* NOTE: #group-free + would be weaker so may be easier to produce, + but should always be able to strengthen before deallocation (only for non-distributed / "real" indices). + For distributed indices, we don't want to force a sync. + if inverse + then formula_desyncgroup idx dim formula + else *) + trm_apps ~annot:formula_annot trm_group [formula_range (trm_int 0) dim (trm_int 1); formula_fun [idx, typ_int] formula] + ) real_inds real_dims inside_formula in let wrap_desyncgroups distrib_inds distrib_dims inside_formula = List.fold_right2 (fun idx dim formula -> - if (inverse) then - (* when free-ing, we expect things to already be synchronized (groups) *) + (* NOTE: #group-free + if inverse then trm_apps ~annot:formula_annot trm_group [formula_range (trm_int 0) dim (trm_int 1); formula_fun [idx, typ_int] formula] - else + else *) trm_apps ~annot:formula_annot trm_desyncgroup [dim; formula_fun [idx, typ_int] formula]) distrib_inds distrib_dims inside_formula in @@ -323,7 +348,10 @@ let desync_alloc_ghosts (inverse: bool) (distrib_dims: trm list) (real_dims: trm formula)) in assume_msize_mult, msize_to_from_mult in - let desync_tile_ghost_f = if inverse then ghost_untile_divides_trivial else ghost_desync_tile_divides_trivial in + let desync_tile_ghost_f = if inverse + (* NOTE: #group-free *) + then ghost_desync_untile_divides_trivial + else ghost_desync_tile_divides_trivial in let dmindex_tile_ghost_f = if inverse then ghost_dmindex_tile else ghost_dmindex_untile in let rec make_ghosts ghosts seen_dims remain_dims = let ghosts = match remain_dims with @@ -519,13 +547,13 @@ let is_smem_or_gmem (f: formula): bool = | _ -> false (* LATER: generic transfos for barrier conversion (take the barrier desired as argument )*) -let%transfo magic_barrier_to_blocksync (kernel_body: target) (tg: target): unit = +let%transfo magic_barrier_to_blocksync ?(mark : mark = no_mark) (kernel_body: target) (tg: target): unit = (* note: blocksync() breaks the strict loop contracts, because it wants a fraction of the KernelParams. Thus, we remove the strict annotations in the entire kernel body. *) Resources.with_non_strict_loop_contracts ([nbAny] @ kernel_body @ [cFor ""]) (fun () -> Target.iter (fun p -> Resources.ensure_computed_at p; - Target.apply_at_path (Gpu_trm.magic_barrier_to_seq block_sync is_smem_or_gmem) p) tg + Target.apply_at_path (fun t -> trm_add_mark mark (Gpu_trm.magic_barrier_to_seq block_sync is_smem_or_gmem t)) p) tg ) let%transfo magic_barrier_to_teardown_sync (tg: target): unit = diff --git a/lib/transfo/loop.ml b/lib/transfo/loop.ml index eb19eb736..b73b81213 100644 --- a/lib/transfo/loop.ml +++ b/lib/transfo/loop.ml @@ -21,7 +21,8 @@ let path_of_loop_surrounding_mark_current_ast (m : mark) : path = loop_path (* internal *) -let rec fission_rec (next_mark : unit -> mark) (nest_of : int) (m_interstice : mark) : unit = +let rec fission_rec (next_mark : unit -> mark) (nest_of : int) + (mark_loops : mark) (m_interstice : mark) : unit = if nest_of > 0 then begin (* Apply fission in innermost loop *) let p_interstice = Target.resolve_mark_exactly_one m_interstice in @@ -53,6 +54,7 @@ let rec fission_rec (next_mark : unit -> mark) (nest_of : int) (m_interstice : m (* TODO: this is required if other transformations like Variable_basic.inline don't eagerly do it. *) Resources.make_strict_loop_contracts [cPath p_loop]; fission_basic ~mark_loops:m_loops ~mark_between_loops:m_between [cPath p_loop_body; cMark m_interstice]; + if nest_of = 1 then Marks.add mark_loops [nbMulti; cMark m_loops]; if !Flags.check_validity || !Flags.use_resources_with_models then begin (* FIXME: hide condition between better API? *) Ghost_pair.minimize_all_in_seq [nbExact 2; cPath p_outer_seq; cMark m_loops; dBody]; Resources.loop_minimize [nbExact 2; cPath p_outer_seq; cMark m_loops]; @@ -62,7 +64,7 @@ let rec fission_rec (next_mark : unit -> mark) (nest_of : int) (m_interstice : m end; (* And go through the outer loops *) - fission_rec next_mark (nest_of - 1) m_between + fission_rec next_mark (nest_of - 1) mark_loops m_between end (** Expects the target [tg] to point somewhere inside the body of a simple loop nest. @@ -82,10 +84,12 @@ let rec fission_rec (next_mark : unit -> mark) (nest_of : int) (m_interstice : m -> beware of nesting, should probably start with innermost paths for each for loop, apply fission on that loop, at the selected indices *) -let%transfo fission ?(nest_of : int = 1) (tg : target) : unit = +let%transfo fission ?(nest_of : int = 1) + ?(mark_loops : mark = no_mark) + (tg : target) : unit = Target.iter (fun p_interstice -> Marks.with_marks (fun next_mark -> let m_interstice = Marks.add_next_mark_on next_mark p_interstice in - fission_rec next_mark nest_of m_interstice + fission_rec next_mark nest_of mark_loops m_interstice )) tg (* TODO: factorize with non-bis @@ -273,7 +277,10 @@ let%transfo hoist ?(tmp_names : string = "${var}_step${i}") where [0] represents a loop for which no dimension should be created, and [1] represents a loop for which a dimension should be created. *) -let%transfo hoist_instr_loop_list (loops : int list) (tg : target) : unit = +let%transfo hoist_instr_loop_list + ?(down : bool = false) (* TODO: infer from destination *) + (loops : int list) + (tg : target) : unit = Trace.tag_valid_by_composition (); Marks.with_marks (fun next_m -> let rec aux (i : int) (remaining_loops : int list) (p : path) : unit = @@ -284,25 +291,38 @@ let%transfo hoist_instr_loop_list (loops : int list) (tg : target) : unit = let instr_mark = next_m () in Trace.step ~kind:Step_group ~name:(sprintf "%d. move out" i) (fun () -> Marks.add instr_mark (target_of_path p); + if down then failwith "downward move out not supported yet"; move_out_bis (target_of_path p); ); - Target.iter (fun p -> aux (i + 1) rl p) [cMark instr_mark]; + (* FIXME: hack on span API differences *) + let target = match Path.extract_last_dir p with + | _, Path.Nth _ -> [cMark instr_mark] + | _ -> [cMarkSpan instr_mark] + in + Target.iter (fun p -> aux (i + 1) rl p) target; | 1 :: rl -> (* create dimension. *) - let (idx, loop_path) = Path.index_in_surrounding_loop p in + let (_idx, loop_path) = Path.span_in_surrounding_loop p in let loop_target = target_of_path loop_path in let instr_mark = next_m () in + let mark_loops = next_m () in Trace.step ~kind:Step_group ~name:(sprintf "%d. hoist" i) (fun () -> Marks.add instr_mark (target_of_path p); - Instr.move_in_seq ~dest:[tFirst] (target_of_path p); - fission (loop_target @ [tAfter; cMark instr_mark]); - ); - aux (i + 1) rl loop_path; + let move_dest = if not down then [tFirst] else [tLast] in + Instr.move_in_seq ~dest:move_dest (target_of_path p); + (* FIXME: hack on span API differences *) + let target = begin match Path.extract_last_dir p with + | _, Path.Nth _ -> if not down then [tAfter; cMark instr_mark] else [tBefore; cMark instr_mark] + | _ -> if not down then [tAfter; cMarkSpanStop instr_mark] else [tBefore; cMarkSpanStart instr_mark] + end in + fission ~mark_loops (loop_target @ target); + let next_loop_path = if not down then loop_path else Target.resolve_target_exactly_one [occLast; cMark mark_loops] in + aux (i + 1) rl next_loop_path) | _ -> failwith "expected list of 0 and 1s" in Target.iter (fun p -> - let tg_trm = Target.resolve_path p in - assert (Option.is_none (trm_let_inv tg_trm)); + (* let tg_trm = Target.resolve_path p in *) + (* assert (Option.is_none (trm_let_inv tg_trm)); *) aux 1 (List.rev loops) p; ) tg) @@ -342,6 +362,7 @@ let%transfo hoist_expr_loop_list (name : string) let targets_iter_with_loop_lists ?(indep : string list = []) ?(dest : target = []) + ?(down : bool = false) (* TODO: infer from destination *) (f : int list -> path -> unit) (tg : target) : unit = begin @@ -359,7 +380,13 @@ begin | _ -> path_fail hoist_relpath "expects [before] to point a sequence surrounding its target" in (* TODO: otherwise, need to move instrs after hoist. *) - assert ((List.hd target_relpath) = (Dir_seq_nth hoist_before_index)); + if not down then begin + if not ((List.hd target_relpath) = (Dir_seq_nth hoist_before_index)) + then path_fail target_relpath "would need to move instrs after hoist."; + end else begin + if not ((List.hd target_relpath) = (Dir_seq_nth (hoist_before_index - 1))) + then path_fail target_relpath "would need to move instrs after hoist."; + end; let (rev_loop_list, _) = List.fold_left (fun (rev_loop_list, p) elem -> let new_rev_loop_list = match trm_for_inv (resolve_path p) with | Some ({ index }, _, _, _) -> @@ -404,6 +431,24 @@ let%transfo hoist_expr (name : string) hoist_expr_loop_list name loops (target_of_path p) ) tg +let%transfo hoist_decl ?(name : string = "") + ?(indep : string list = []) + ?(dest : target = []) + (tg : target) : unit = + Trace.tag_valid_by_composition (); + targets_iter_with_loop_lists ~indep ~dest (fun loops p -> + hoist_decl_loop_list ~name loops (target_of_path p) + ) tg + +let%transfo hoist_instr + ?(dest : target = []) + ?(down : bool = false) (* TODO: infer from destination *) + (tg : target) : unit = + Trace.tag_valid_by_composition (); + targets_iter_with_loop_lists ~dest ~down (fun loops p -> + hoist_instr_loop_list ~down loops (target_of_path p) + ) tg + (* *) let%transfo simpl_scoped_ghosts (ghosts_before : trm list) (ghosts_after : trm list) (p_span : path) : unit = Trace.justif_always_correct (); diff --git a/tests/loop/hoist_instr/loop_hoist_instr.cpp b/tests/loop/hoist_instr/loop_hoist_instr.cpp new file mode 100644 index 000000000..c43cb2fbd --- /dev/null +++ b/tests/loop/hoist_instr/loop_hoist_instr.cpp @@ -0,0 +1,25 @@ +#include + +void f(int* t) { + __writes("t ~> Matrix2(4, 4, fun (ij km: int) -> 0)"); + + __ghost(tile_divides, "size := 4, tile_count := 2, tile_size := 2, items := fun ij -> for km in 0..4 -> &t[MINDEX2(4, 4, ij, km)] ~> UninitCell"); + for (int i = 0; i < 2; i++) { + __xwrites("for j in 0..2 -> for km in 0..4 -> &t[MINDEX2(4, 4, i*2 + j, km)] ~~> 0"); + + for (int j = 0; j < 2; j++) { + __xwrites("for km in 0..4 -> &t[MINDEX2(4, 4, i*2 + j, km)] ~~> 0"); + + __ghost(tile_divides, "size := 4, tile_count := 2, tile_size := 2, items := fun km -> &t[MINDEX2(4, 4, i*2 + j, km)] ~> UninitCell"); + for (int k = 0; k < 2; k++) { + __xwrites("for m in 0..2 -> &t[MINDEX2(4, 4, i*2 + j, k*2 + m)] ~~> 0"); + for (int m = 0; m < 2; m++) { + __xwrites("&t[MINDEX2(4, 4, i*2 + j, k*2 + m)] ~~> 0"); + t[MINDEX2(4, 4, i*2 + j, k*2 + m)] = 0; + } + } + __ghost(untile_divides, "size := 4, tile_count := 2, tile_size := 2, items := fun km -> &t[MINDEX2(4, 4, i*2 + j, km)] ~~> 0"); + } + } + __ghost(untile_divides, "size := 4, tile_count := 2, tile_size := 2, items := fun ij -> for km in 0..4 -> &t[MINDEX2(4, 4, ij, km)] ~~> 0"); +} diff --git a/tests/loop/hoist_instr/loop_hoist_instr.ml b/tests/loop/hoist_instr/loop_hoist_instr.ml new file mode 100644 index 000000000..d487b2b47 --- /dev/null +++ b/tests/loop/hoist_instr/loop_hoist_instr.ml @@ -0,0 +1,10 @@ +open Optitrust +open Prelude + +(* let _ = Flags.save_ast_for_steps := Some Flags.Steps_all *) + +let _ = Run.script_cpp (fun () -> + !! Resources.ensure_computed (); + !! Loop.hoist_instr ~dest:[tAfter; cFor "i"] ~down:true [cForBody "j"; dSeqNth 2]; + !! Loop.hoist_instr ~dest:[tBefore; occFirst; cFor "i"] [occFirst; cForBody "j"; dSeqNth 0]; +) diff --git a/tests/loop/hoist_instr/loop_hoist_instr_exp.cpp b/tests/loop/hoist_instr/loop_hoist_instr_exp.cpp new file mode 100644 index 000000000..eb10f82ae --- /dev/null +++ b/tests/loop/hoist_instr/loop_hoist_instr_exp.cpp @@ -0,0 +1,72 @@ +#include + +void f(int* t) { + __writes("t ~> Matrix2(4, 4, fun (ij: int) (km: int) -> 0)"); + __ghost(tile_divides, + "size := 4, tile_count := 2, tile_size := 2, items := fun ij -> for " + "km in 0..4 -> &t[MINDEX2(4, 4, ij, km)] ~> UninitCell"); + for (int i = 0; i < 2; i++) { + __strict(); + __xconsumes( + "for j in 0..2 -> for km in 0..4 -> &t[MINDEX2(4, 4, i * 2 + j, km)] " + "~> UninitCell"); + __xproduces( + "for j in 0..2 -> for bi in 0..2 -> for i1 in 0..2 -> &t[MINDEX2(4, 4, " + "i * 2 + j, bi * 2 + i1)] ~> UninitCell"); + for (int j = 0; j < 2; j++) { + __strict(); + __xconsumes( + "for km in 0..4 -> &t[MINDEX2(4, 4, i * 2 + j, km)] ~> UninitCell"); + __xproduces( + "for bi in 0..2 -> for i1 in 0..2 -> &t[MINDEX2(4, 4, i * 2 + j, bi " + "* 2 + i1)] ~> UninitCell"); + __ghost(tile_divides, + "size := 4, tile_count := 2, tile_size := 2, items := fun km -> " + "&t[MINDEX2(4, 4, i * 2 + j, km)] ~> UninitCell"); + } + } + for (int i = 0; i < 2; i++) { + __strict(); + __xwrites( + "for j in 0..2 -> for k in 0..2 -> for m in 0..2 -> &t[MINDEX2(4, 4, i " + "* 2 + j, k * 2 + m)] ~~> 0"); + for (int j = 0; j < 2; j++) { + __strict(); + __xwrites( + "for k in 0..2 -> for m in 0..2 -> &t[MINDEX2(4, 4, i * 2 + j, k * 2 " + "+ m)] ~~> 0"); + for (int k = 0; k < 2; k++) { + __strict(); + __xwrites( + "for m in 0..2 -> &t[MINDEX2(4, 4, i * 2 + j, k * 2 + m)] ~~> 0"); + for (int m = 0; m < 2; m++) { + __strict(); + __xwrites("&t[MINDEX2(4, 4, i * 2 + j, k * 2 + m)] ~~> 0"); + t[MINDEX2(4, 4, i * 2 + j, k * 2 + m)] = 0; + } + } + } + } + for (int i = 0; i < 2; i++) { + __strict(); + __xconsumes( + "for j in 0..2 -> for k in 0..2 -> for m in 0..2 -> &t[MINDEX2(4, 4, i " + "* 2 + j, k * 2 + m)] ~~> 0"); + __xproduces( + "for j in 0..2 -> for km in 0..4 -> &t[MINDEX2(4, 4, i * 2 + j, km)] " + "~~> 0"); + for (int j = 0; j < 2; j++) { + __strict(); + __xconsumes( + "for k in 0..2 -> for m in 0..2 -> &t[MINDEX2(4, 4, i * 2 + j, k * 2 " + "+ m)] ~~> 0"); + __xproduces("for km in 0..4 -> &t[MINDEX2(4, 4, i * 2 + j, km)] ~~> 0"); + __ghost(untile_divides, + "size := 4, tile_count := 2, tile_size := 2, items := fun km -> " + "&t[MINDEX2(4, 4, i * 2 + j, km)] ~~> 0"); + } + } + __ghost(untile_divides, + "size := 4, tile_count := 2, tile_size := 2, items := fun ij -> for " + "km in 0..4 -> &t[MINDEX2(4, 4, ij, km)] ~~> 0"); +} From cb2f26cbc6721cbd7da136d490480564a1d2ff0d Mon Sep 17 00:00:00 2001 From: Thomas Koehler Date: Mon, 6 Jul 2026 18:04:46 +0200 Subject: [PATCH 05/23] print treg set/get --- case_studies/gpu/matmul/matmul.ml | 2 +- case_studies/gpu/matmul/matmul_exp.cu | 106 ++++++++++++++++++++++++++ lib/framework/c/cuda_lowering.ml | 4 + 3 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 case_studies/gpu/matmul/matmul_exp.cu diff --git a/case_studies/gpu/matmul/matmul.ml b/case_studies/gpu/matmul/matmul.ml index 3c2dfc55c..13e6e5e9e 100644 --- a/case_studies/gpu/matmul/matmul.ml +++ b/case_studies/gpu/matmul/matmul.ml @@ -8,7 +8,7 @@ let _ = Flags.disable_stringreprs := true let _ = Flags.save_ast_for_steps := Some Steps_important (* Flags.Steps_script *) (* let _ = Flags.report_exectime := true *) -let stage_ok = fun i -> i >= 7 +let stage_ok = fun i -> i = 7 let bm = 32 let bn = 32 diff --git a/case_studies/gpu/matmul/matmul_exp.cu b/case_studies/gpu/matmul/matmul_exp.cu new file mode 100644 index 000000000..c00216f9b --- /dev/null +++ b/case_studies/gpu/matmul/matmul_exp.cu @@ -0,0 +1,106 @@ + +#include + + + + + + +const int bm = 32; + +const int bn = 32; + +const int bk = 4; + +const int tn = 4; + +const int tm = 8; + + __global__ void __kernel0 (float* b_gmem, float* a_gmem, float* c_gmem, int p, int n, int m +) { + const int __ctx_sz = MSIZE2(exact_div(m, 32), exact_div(n, 32)) * MSIZE2(exact_div(32, 8), exact_div(32, 4)); + const int __tid = blockIdx.x * MSIZE2(exact_div(32, 8), exact_div(32, 4)) + threadIdx.x; + SharedMemory smem; + float* const b_smem = (float*) smem.ptr(MSIZE3(8, 4, 4)); + float* const a_smem = (float*) smem.ptr(MSIZE3(4, 4, 8)); + const int __ctx_sz_0 = __ctx_sz / (exact_div(m, 32)); + const int __bi0 = __tid % __ctx_sz / __ctx_sz_0; + const int __ctx_sz_1 = __ctx_sz_0 / (exact_div(n, 32)); + const int __bj1 = __tid % __ctx_sz_0 / __ctx_sz_1; + const int __ctx_sz_2 = __ctx_sz_1 / 4; + const int __ti2 = __tid % __ctx_sz_1 / __ctx_sz_2; + const int __ctx_sz_3 = __ctx_sz_2 / 8; + const int __tj3 = __tid % __ctx_sz_2 / __ctx_sz_3; + const int __ctx_sz_4 = __ctx_sz_1 / 4; + const int __ti4 = __tid % __ctx_sz_1 / __ctx_sz_4; + const int __ctx_sz_5 = __ctx_sz_4 / 8; + const int __i5 = __tid % __ctx_sz_4 / __ctx_sz_5; + const int __ctx_sz_6 = __ctx_sz_1 / 8; + const int __tj6 = __tid % __ctx_sz_1 / __ctx_sz_6; + const int __ctx_sz_7 = __ctx_sz_6 / 4; + const int __k7 = __tid % __ctx_sz_6 / __ctx_sz_7; + const int __ctx_sz_8 = __ctx_sz_1 / 4; + const int __ti8 = __tid % __ctx_sz_1 / __ctx_sz_8; + const int __ctx_sz_9 = __ctx_sz_8 / 8; + const int __tj9 = __tid % __ctx_sz_8 / __ctx_sz_9; + const int __ctx_sz_10 = __ctx_sz_1 / 4; + const int __ti10 = __tid % __ctx_sz_1 / __ctx_sz_10; + const int __ctx_sz_11 = __ctx_sz_10 / 8; + const int __tj11 = __tid % __ctx_sz_10 / __ctx_sz_11; + float* const sum = __treg_ref_uninit2(8, 4); + for (int i = 0; i < 8; i++) { + for (int j = 0; j < 4; j++) { + sum[MINDEX3(4 * 8, 8, 4, 0, i, j)] = 0.f; + } + } + for (int bkIdx = 0; bkIdx < exact_div(p, 4); bkIdx++) { + for (int k = 0; k < 4; k++) { + a_smem[MINDEX4(exact_div(m, 32) * (exact_div(n, 32)), 4, 4, 8, 0, __ti4, k, __i5)] = a_gmem[MINDEX2(m, p, __bi0 * 32 + ( + __ti4 * 8 + __i5), bkIdx * 4 + k)]; + } + for (int j = 0; j < 4; j++) { + b_smem[MINDEX4(exact_div(m, 32) * (exact_div(n, 32)), 8, 4, 4, 0, __tj6, __k7, j)] = b_gmem[MINDEX2(p, n, bkIdx * 4 + __k7, __bj1 * 32 + ( + __tj6 * 4 + j))]; + } + __syncthreads(); + for (int i = 0; i < 8; i++) { for (int j = 0; j < 4; j++) { } } + for (int k = 0; k < 4; k++) { + float* const a_regs = __treg_ref_uninit1_s(8); + for (int i = 0; i < 8; i++) { + a_regs[MINDEX1(8, i)] = a_smem[MINDEX4(exact_div(m, 32) * (exact_div(n, 32) + ), 4, 4, 8, 0, __ti8, k, i)]; + } + float* const b_regs = __treg_ref_uninit1_s(4); + for (int j = 0; j < 4; j++) { + b_regs[MINDEX1(4, j)] = b_smem[MINDEX4(exact_div(m, 32) * (exact_div(n, 32) + ), 8, 4, 4, 0, __tj9, k, j)]; + } + for (int i = 0; i < 8; i++) { + for (int j = 0; j < 4; j++) { + sum[MINDEX3(4 * 8, 8, 4, 0, i, j)] = sum[MINDEX3(4 * 8, 8, 4, 0, i, j)] + a_regs[MINDEX1(8, i)] * b_regs[MINDEX1(4, j)]; + } + } + } + for (int i = 0; i < 8; i++) { for (int j = 0; j < 4; j++) { } } + } + for (int i = 0; i < 8; i++) { + for (int j = 0; j < 4; j++) { + c_gmem[MINDEX2(m, n, __bi0 * 32 + (__ti10 * 8 + i), __bj1 * 32 + (__tj11 * 4 + j + ))] = sum[MINDEX3(4 * 8, 8, 4, 0, i, j)]; + } + } +} + + void mm (float* c, float* a, float* b, int m, int n, int p) { + float* const c_gmem = __gmem_malloc2(m, n); + float* const a_gmem = __gmem_malloc2(m, p); + memcpy_host_to_device2(a_gmem, a, m, p); + float* const b_gmem = __gmem_malloc2(p, n); + memcpy_host_to_device2(b_gmem, b, p, n); + __kernel0<<>>(b_gmem, a_gmem, c_gmem, p, n, m); + gmem_free(b_gmem); + gmem_free(a_gmem); + memcpy_device_to_host2(c, c_gmem, m, n); + gmem_free(c_gmem); +} diff --git a/lib/framework/c/cuda_lowering.ml b/lib/framework/c/cuda_lowering.ml index f07341013..2e1bb9d5d 100644 --- a/lib/framework/c/cuda_lowering.ml +++ b/lib/framework/c/cuda_lowering.ml @@ -75,10 +75,12 @@ let flatten_thread_loops (ctx_size: var) (tid: var) (t: trm): trm = let is_gpu_get_operation (v: var): bool = (var_has_name var__gmem_get.name v) || (var_has_name var__smem_get.name v) + || (var_has_name var__treg_get.name v) let is_gpu_set_operation (v: var): bool = (var_has_name var__gmem_set.name v) || (var_has_name var__smem_set.name v) + || (var_has_name var__treg_set.name v) let is_any_mem_operation (p: prim): bool = match p with @@ -136,6 +138,8 @@ let lower_smem_alloc (t: trm): trm option = ) ] +(* TODO: lower __treg_ref_uninitN __treg_ref_uninitN_s *) + let lower_host_fn (bound_vars_typs: typ varmap ref) (k_id: int ref) (t: trm): trm = let rec scan_bound_vars t = ( trm_iter scan_bound_vars t; From 7d7d1abddc2f21497021c94252662c5f30729fde Mon Sep 17 00:00:00 2001 From: Thomas Koehler Date: Thu, 9 Jul 2026 16:34:26 +0200 Subject: [PATCH 06/23] =?UTF-8?q?add=20notes=20on=20install=20for=20Cl?= =?UTF-8?q?=C3=A9ment?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- INSTALL.md | 9 ++++++++- README.md | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/INSTALL.md b/INSTALL.md index 79d0a294b..399f10916 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -147,7 +147,7 @@ Follow to the next section to test that your OptiTrust installation works. ## OptiTrust setup -### Install precommit hooks +### DEPRECATED: Install precommit hooks This command configures git to automatically run unit tests between commits. It can be ignored if you just want to try OptiTrust without contributing, and you have not downloaded the source files through git. @@ -204,6 +204,7 @@ may want to add into your `~/.bashrc` the line: ``` (or use `sudo ln -s /usr/bin/codium /usr/bin/code`). +NEW : there is now a VSCode extension that can be installed by following the instructions in `tools/vscode-optitrust/README.md`. ### Direnv setup for automatic Nix shell activation in VSCode (experimental) @@ -222,6 +223,8 @@ Once installed, when you open the OptiTrust repo in VScode, you should first be -------------------------------------------------------------------------------- ## Browser installation +NOTE: not necessary if you use the new VSCode extension. + NOTE: If you're using the Nix shell, don't try to install a browser in the Nix environment, install it on the system as you would normally. Recommended: installation of Chromium browser, which is very fast for @@ -281,6 +284,8 @@ Alternatively, use the quick open prompt (`ctrl+p`), then paste `ext install oca ### Install the OptiTrust shortcuts for VSCode +NOTE: not necessary if you use the new VSCode extension setup. + In VSCode, open the file `~/.config/Code/User/keybindings.json`. For VSCodium, this file is located at `~/.config/VSCodium/User/keybindings.json`. If you have an empty file, paste the following contents. @@ -511,6 +516,8 @@ matrix-multiply case study. ### Viewing keyboard shortcuts +TODO: check if still relevant to the new VSCode extension setup. + It may not be easy at first to recall all the shortcuts. Besides using a sticker at the bottom of your screen, you can use the command `./shortcuts.sh` to display the shortcuts, and in VSCode use menu File / Preferences / Keyboard Shortcuts, diff --git a/README.md b/README.md index b13f4cb22..24c967916 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ If you are interested in a demo, please get in touch with @charguer. # Steps for using OptiTrust - See `INSTALL.md` for installation procedure, to set up the right version of OCaml/Clang/ClangML and configure VSCode/Codium, in particular. +- See `tools/vscode-optitrust/README.md` to set up the new VSCode extension (still being refined). - See `INSTALL_EXTRA.md` for a list of additional useful tools for program optimization. - See `VSCODE_CUSTOMIZE.md` for useful tips for using VScode or VScodium. - Read the text below for high level comments on the organization of the repository. From 878efff288cf9c3f5efe195b0b8dd5a7b6dac635 Mon Sep 17 00:00:00 2001 From: Thomas Koehler Date: Thu, 9 Jul 2026 16:37:17 +0200 Subject: [PATCH 07/23] bis --- README.md | 4 +++- doc/interact.md | 16 ++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 24c967916..251162200 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ If you are interested in a demo, please get in touch with @charguer. - See `INSTALL_EXTRA.md` for a list of additional useful tools for program optimization. - See `VSCODE_CUSTOMIZE.md` for useful tips for using VScode or VScodium. - Read the text below for high level comments on the organization of the repository. -- Check out `case_studies/matmul/matmul_check.ml` and `matmul_check.cpp` to begin with---to produce a full trace you may need a lot of RAM. +- Check out `case_studies/dot_product/dot.ml` and `dot.cpp` to begin with---to produce a full trace you may need a lot of RAM. # Overview of the implementation @@ -60,6 +60,8 @@ In the `tests` and `case_studies` folders, for each unit test and each case stud - `_out.cpp` (not committed): contains the optimized code, produced when executing the `.ml` script. - `_exp.cpp`: is a git-versioned copy of `_out.cpp`; the tester claims success if the `_out.cpp` matches the `_exp.cpp`; if legitimate changes are applied to the test, the `_exp.cpp` file should be manually updated to match the `_out.cpp` file (e.g., using `cp` or using the dedicated `./tester fixexp` command). +TODO: update paragraphs below + When producing a trace (see shortcuts in `INSTALL.md`), the trace opens in a browser. In the trace display, on a given step, there are options to control the display: - mode: `diff` between before-step and after-step, `code before` and `code after` for seeing the code in full before or after the step. If the diff for a step is empty, only the code is displayed. - `decode`: to see the internal representation of the AST diff --git a/doc/interact.md b/doc/interact.md index 31066ecd8..cf033e2dd 100644 --- a/doc/interact.md +++ b/doc/interact.md @@ -12,11 +12,11 @@ in the instructions from `INSTALL.md`. For example, `F6` runs the task named ## Description of a task -The project file `.vscode/tasks.json` describes the tasks. Consider e.g. +The project file `.vscode/tasks.json` describes the tasks. Consider e.g. "view diff". This task executes a script `tools/view_results.sh`. -The argument provided to the script is "step_diff" to indicate what result +The argument provided to the script is "step_diff" to indicate what result we want to visualize, and the path of the current script as well as the cursor -line are passed to the script. +line are passed to the script. ```json { @@ -38,7 +38,7 @@ line are passed to the script. "${lineNumber}" ] }, -``` +``` Note: the option "-i" is to allow launching GUI tasks, it might not be stricly necessary if the "run_action" wrapper uses a auxiliary "watcher" process. @@ -64,7 +64,7 @@ The html file is then opened using the script `tools/open_in_browser.sh`. ## Purpose and working of open_trace -The script `tools/open_trace.sh` is meant to open an interactive trace. +The script `tools/open_trace.sh` is meant to open an interactive trace. If the mode "standalone-full-trace" is used, the trace is computed a standalone trace, following the same approach as for "open_diff". However, the typical usage, which scales up better, is to produce a webpage using only the meta-data describing the steps in the trace. The rendering of each individual step is computed only on-demand, by means of a client-server interaction. @@ -76,7 +76,7 @@ The script `open_trace.sh` first compiles the server (to ensure that its binary Then, the script `open_trace.sh` opens the webpage at the URL: `http://localhost:6775/myscript_trace.html`, assuming `myscript.ml` to be the user script. The implementation of the server is found in `tools/trace_server/trace_server.ml`. -The serialization of the trace is performed in the function `dump_full_trace_to_js`, +The serialization of the trace is performed in the function `dump_full_trace_to_js`, when the flag `Flags.request_serialized_trace` is set, as is the case in mode "full_trace". ## Purpose and working of open_in_browser @@ -94,9 +94,9 @@ Due to VScode sandboxing, in most set-ups, the VScode tasks are generally unable The `run_action.sh` script implements tooling to work around limitations of VScode, which executes tasks in a sandbox, hence is not able to properly execute features such as launching an external browser or running "xdotool" for giving the focus to a given window. This limitations are especially visible when VScode and/or the brower is installed using Snap, but even with a direct binary installation, VScode performs some form of sandboxing. -The script `run_action.sh` takes as argument a command line to execute, and writes this command line into a temporary file named `action.sh`. +The script `run_action.sh` takes as argument a command line to execute, and writes this command line into a temporary file named `action.sh`. -Independently, the OptiTrust user needs to execute a script named `watch.sh` that runs in the background. It is launched by means of the command `./watcher.sh`, which is just a shorthand for `./.vscode/watch.sh`. This script waits to observe modifications to the file `action.sh` (using the "inotify" tooling). When the script detects a change, it executes the command line found in `action.sh`. +Independently, the OptiTrust user needs to execute a script named `watch.sh` that runs in the background. It is launched by means of the command `./watcher.sh`, which is just a shorthand for `./.vscode/watch.sh`. This script waits to observe modifications to the file `action.sh` (using the "inotify" tooling). When the script detects a change, it executes the command line found in `action.sh`. The output of that script is captured in a file named `action_out.txt`, whose contents is then reported as output of `action.sh`. This way, the user obtains the feedback of the requested command in the integrated terminal of VScode. From e850f4141606babfacf30455ce75d0cbfaa4c1fc Mon Sep 17 00:00:00 2001 From: Thomas Koehler Date: Fri, 10 Jul 2026 09:26:04 +0200 Subject: [PATCH 08/23] fix tests and add matmul_opt.cu --- case_studies/gpu/README.md | 15 +- case_studies/gpu/matmul/matmul_opt.cu | 148 ++++++++++++++++++ tests/loop/moveout/loop_moveout_basic_exp.cpp | 2 + 3 files changed, 163 insertions(+), 2 deletions(-) create mode 100644 case_studies/gpu/matmul/matmul_opt.cu diff --git a/case_studies/gpu/README.md b/case_studies/gpu/README.md index 2c096105c..59b786651 100644 --- a/case_studies/gpu/README.md +++ b/case_studies/gpu/README.md @@ -1,8 +1,11 @@ # GPU/CUDA case studies -These case studies are GPU kernels written in OptiTrust, using language extensions for representing GPU programs (OptiGPU). Unless otherwise noted these algorithms all come from the official [cuda samples repository](https://github.com/NVIDIA/cuda-samples/tree/c94ff366aed18c797b8a85dfaac7817b0228b420). Several of them have an `_opt.cu` file in the case studies directory explaining in plain english how the optimized kernel is obtained, as a supplement. The "_gpu.cpp" file in each directory is a handwritten implementation of the GPU program in OptiTrust, i.e. generating GPU code from OptiTrust without making use of the transformations. +These case studies are GPU kernels written in OptiTrust, using language extensions for representing GPU programs (OptiGPU). + +Several case studies have an `_opt.cu` file in the case studies directory explaining in plain english how the optimized kernel is obtained, as a supplement. The "_gpu.cpp" file in each directory is a handwritten implementation of the GPU program in OptiTrust, i.e. generating GPU code from OptiTrust without making use of the transformations. + +## Kernels from the official [CUDA samples repository](https://github.com/NVIDIA/cuda-samples/tree/c94ff366aed18c797b8a85dfaac7817b0228b420) -Description/status of each: * [`vector_add`](https://github.com/NVIDIA/cuda-samples/blob/c94ff366aed18c797b8a85dfaac7817b0228b420/Samples/0_Introduction/vectorAdd/vectorAdd.cu): add a constant to a vector - [x] Full functional correctness - [x] Optimized GPU version @@ -22,3 +25,11 @@ Description/status of each: - [ ] Unoptimized GPU version - [ ] Optimized GPU version - [ ] CPU->GPU Transformation script + +## Kernels from blogs + +* [`matmul`](https://github.com/siboehm/SGEMM_CUDA/tree/master/src/kernels): optimized matmul (adapted from [Simon Boehm's blog](https://siboehm.com/articles/22/CUDA-MMM), not from CUDA samples) with coalescing and hierarchical tiling for shared memory and thread registers storage + - [X] Full functional correctness + - [X] Optimized GPU version + - [x] CPU->GPU Transformation script + - [ ] Explicit vectorization, tensor cores, async double buffering diff --git a/case_studies/gpu/matmul/matmul_opt.cu b/case_studies/gpu/matmul/matmul_opt.cu new file mode 100644 index 000000000..377fb94a3 --- /dev/null +++ b/case_studies/gpu/matmul/matmul_opt.cu @@ -0,0 +1,148 @@ +// Code adapted from https://github.com/siboehm/SGEMM_CUDA/blob/5a7dcc513d951ba764d51bc9d587b3163f3a894d/src/kernels/6_kernel_vectorize.cuh + +#include +#include +// #include + +//// BEGIN TUNING PARAMS +// BM divides rows +#define BM 32 +// BN divides cols +#define BN 32 +// BK divides shared +#define BK 16 +// TM divides BM +#define TM 8 +// TN divides BN +#define TN 8 +//// END TUNING PARAMS + +#define GRID_DIM(rows, cols) ((rows)/BM * ((cols)/BN)) +// COMMENT: I would usually use blockDim.x, +// but this may be helping the compiler more +#define BLOCK_DIM (BM/TM * (BN/TN)) + + +__global__ +void blocktiling2d( + float_t alpha, + float_t beta, + uint32_t shared, + uint32_t cols, + float_t *gA, + float_t *gB, + float_t *gC +) { + // shared memory cache + // many hand written implementations would use: + // __shared__ float_t sA[BM*BK]; + // __shared__ float_t sB[BK*BN]; + // but this leads to less flexibility in allocating shared memory + // instead use dynamic shared memory with + // size in bytes == (BM*BK + BK*BN) * (sizeof(float_t)) + extern __shared__ float_t buffer[]; + float_t *sA = buffer; + float_t *sB = &buffer[BM * BK]; + + // thread local cache + float_t rAcol[TM]; + float_t rBrow[TN]; + float_t rchProd[TM][TN]; + + uint32_t num_n_tiles = cols / BN; + // for each block, jump to beginning of tile row in gA + uint32_t mrow = blockIdx.x / num_n_tiles; + gA += shared * (mrow * BM); + // for each block, jump to beginning of tile column in gB + uint32_t mcol = blockIdx.x % num_n_tiles; + gB += mcol * BN; + // for each block, jump to the beginnin of the result tile in gC + gC += mrow * BM * cols + mcol * BN; + + // row and column for each thread tile within the block tile + uint32_t threadRow = threadIdx.x / (BN / TN); + uint32_t threadCol = threadIdx.x % (BN / TN); + + for (uint32_t bkIdx = 0; bkIdx < shared; bkIdx += BK) { + __syncthreads(); + // load A vectorized and transposed into shared memory + for (uint32_t i = 0; i < BM * BK; i += BLOCK_DIM * 4) { + uint32_t row = (i + threadIdx.x * 4) / BK; + uint32_t col = (i + threadIdx.x * 4) % BK; + + // COMMENT: Instead of using bkIdx in the indexing, we could make sure + // to advance gA and gB to the next blockTile every iteration. + // gA += BK; + // gB += BK * cols; + // In that case, bkIdx is never used anywhere. I find this unintuitive. + float4 tmp = reinterpret_cast(&gA[bkIdx + shared * row + col])[0]; + sA[(col + 0) * BM + row] = tmp.x; + sA[(col + 1) * BM + row] = tmp.y; + sA[(col + 2) * BM + row] = tmp.z; + sA[(col + 3) * BM + row] = tmp.w; + } + // load B vectorized into shared memory + for (uint32_t i = 0; i < BK * BN; i += BLOCK_DIM * 4) { + uint32_t row = (i + threadIdx.x * 4) / BN; + uint32_t col = (i + threadIdx.x * 4) % BN; + + reinterpret_cast(&sB[row * BN + col])[0] = + reinterpret_cast(&gB[cols * bkIdx + cols * row + col])[0]; + } + __syncthreads(); + + // compute subproducts per thread tile + for (uint32_t dotIdx = 0; dotIdx < BK; dotIdx++) { + for (uint32_t i = 0; i < TM; i++) { + rAcol[i] = sA[dotIdx * BM + threadRow * TM + i]; + } + for (uint32_t i = 0; i < TN; i++) { + rBrow[i] = sB[dotIdx * BN + threadCol * TN + i]; + } + for (uint32_t resIdxM = 0; resIdxM < TM; resIdxM++) { + for (uint32_t resIdxN = 0; resIdxN < TN; resIdxN++) + rchProd[resIdxM][resIdxN] += + rAcol[resIdxM] * rBrow[resIdxN]; + } + } + } + + // scale results of gA*gB, add scaled values from gC and write back into gC + for (uint32_t resIdxM = 0; resIdxM < TM; resIdxM++) { + for (uint32_t resIdxN = 0; resIdxN < TN; resIdxN++) { + float_t *outElem = + &gC[(threadRow * TM + resIdxM) * cols + threadCol * TN + resIdxN]; + outElem[0] = beta * outElem[0] + alpha * rchProd[resIdxM][resIdxN]; + } + } +} + +void check_error(cudaError_t err, const char *file, int line) +{ + if (err != cudaSuccess) { + std::cerr << "ERROR -- " << file << ":" << "line" << std::endl; + std::cerr << "Reason: " << cudaGetErrorString(err); + exit(1); + } +} +#define ERROR(err) check_error(err, __FILE__, __LINE__) + +void +blocktiling2d_host( + float_t alpha, + float_t beta, + uint32_t rows, + uint32_t shared, + uint32_t cols, + float_t *gA, + float_t *gB, + float_t *gC +) { + uint32_t nblk = GRID_DIM(rows, cols); + uint32_t nthr = BLOCK_DIM; + ERROR(cudaFuncSetAttribute(blocktiling2d, + cudaFuncAttributeMaxDynamicSharedMemorySize, + (BM*BK + BK*BN) * sizeof(float_t))); + blocktiling2d<<>>(alpha, beta, shared, cols, gA, gB, gC); + ERROR(cudaDeviceSynchronize()); +} diff --git a/tests/loop/moveout/loop_moveout_basic_exp.cpp b/tests/loop/moveout/loop_moveout_basic_exp.cpp index 4b6effd01..760e57141 100644 --- a/tests/loop/moveout/loop_moveout_basic_exp.cpp +++ b/tests/loop/moveout/loop_moveout_basic_exp.cpp @@ -138,7 +138,9 @@ void test(int* t) { for (int j = 0; j < 10; j++) { __strict(); __smodifies("&x ~> Cell"); + __smodifies("AutoFree(&x, &x ~> UninitCell)"); __smodifies("&s ~> Cell"); + __smodifies("AutoFree(&s, &s ~> UninitCell)"); __smodifies("&t[MINDEX1(10, i)] ~> UninitCell"); __sreads("&a ~> Cell"); __sreads("&b ~> Cell"); From af688609802e535233a25fb29f8f46015fb626c4 Mon Sep 17 00:00:00 2001 From: Thomas Koehler Date: Fri, 10 Jul 2026 17:46:24 +0200 Subject: [PATCH 09/23] make sure three gpu case studies run green --- case_studies/gpu/matmul/matmul.ml | 4 +- case_studies/gpu/matmul/matmul_almost_opt.cpp | 108 ++ case_studies/gpu/matmul/matmul_exp.cpp | 1105 +++++++++++++++-- case_studies/gpu/reduction/reduce.ml | 5 +- case_studies/gpu/reduction/reduce_exp.cpp | 2 +- case_studies/gpu/transpose/transpose.ml | 4 +- case_studies/gpu/transpose/transpose_exp.cpp | 487 ++++++-- .../resources/resource_computation.ml | 6 + lib/framework/resources/resource_formula.ml | 17 + lib/framework/resources/resource_trm.ml | 18 + lib/transfo/gpu.ml | 16 +- lib/transfo/gpu_basic.ml | 4 +- lib/transfo/loop_basic.ml | 29 +- 13 files changed, 1574 insertions(+), 231 deletions(-) create mode 100644 case_studies/gpu/matmul/matmul_almost_opt.cpp diff --git a/case_studies/gpu/matmul/matmul.ml b/case_studies/gpu/matmul/matmul.ml index 13e6e5e9e..4ad32dde1 100644 --- a/case_studies/gpu/matmul/matmul.ml +++ b/case_studies/gpu/matmul/matmul.ml @@ -5,10 +5,10 @@ let _ = Flags.check_validity := true (* FIXME: this flag behaviour needs to be c let _ = Flags.pretty_matrix_notation := false let _ = Flags.recompute_resources_between_steps := false let _ = Flags.disable_stringreprs := true -let _ = Flags.save_ast_for_steps := Some Steps_important (* Flags.Steps_script *) +let _ = Flags.save_ast_for_steps := Some Steps_effectful (* Flags.Steps_script *) (* let _ = Flags.report_exectime := true *) -let stage_ok = fun i -> i = 7 +let stage_ok = fun i -> true (* i = 7 *) let bm = 32 let bn = 32 diff --git a/case_studies/gpu/matmul/matmul_almost_opt.cpp b/case_studies/gpu/matmul/matmul_almost_opt.cpp new file mode 100644 index 000000000..7475c8ef0 --- /dev/null +++ b/case_studies/gpu/matmul/matmul_almost_opt.cpp @@ -0,0 +1,108 @@ +#include + + + + + +const int bm = 32; + +const int bn = 32; + +const int bk = 4; + +const int tn = 4; + +const int tm = 8; + + void mm (float* c, float* a, float* b, int m, int n, int p) { + float* const c_gmem = (float*) malloc(m * n * sizeof(float)); + float* const a_gmem = (float*) malloc(m * p * sizeof(float)); + for (int i1 = 0; i1 < m; i1++) { + for (int i2 = 0; i2 < p; i2++) { + a_gmem[i1 * p + i2] = a[i1 * p + i2]; + } + } + float* const b_gmem = (float*) malloc(n * p * sizeof(float)); + for (int i1 = 0; i1 < p; i1++) { + for (int i2 = 0; i2 < n; i2++) { + b_gmem[i1 * n + i2] = b[i1 * n + i2]; + } + } + float* const a_smem = (float*) malloc(exact_div(4 * 4 * 8 * m * n, (32 * 32 + )) * sizeof(float)); + float* const b_smem = (float*) malloc(exact_div(8 * 4 * 4 * m * n, (32 * 32 + )) * sizeof(float)); + for (int bi = 0; bi < exact_div(m, 32); bi++) { + for (int bj = 0; bj < exact_div(n, 32); bj++) { + float* const sum = (float*) malloc(4 * 8 * 8 * 4 * sizeof(float)); + for (int ti = 0; ti < 4; ti++) { + for (int tj = 0; tj < 8; tj++) { + for (int i = 0; i < 8; i++) { + for (int j = 0; j < 4; j++) { + sum[ti * 8 * 8 * 4 + tj * 8 * 4 + 4 * i + j] = 0.f; + } + } + } + } + for (int bkIdx = 0; bkIdx < exact_div(p, 4); bkIdx++) { + for (int ti = 0; ti < 4; ti++) { + for (int k = 0; k < 4; k++) { + for (int i = 0; i < 8; i++) { + a_smem[exact_div(bi * n * 4 * 4 * 8, 32) + bj * 4 * 4 * 8 + ti * 4 * 8 + 8 * k + i] = a_gmem[( + 32 * bi + 8 * ti + i) * p + 4 * bkIdx + k]; + } + } + } + for (int tj = 0; tj < 8; tj++) { + for (int k = 0; k < 4; k++) { + for (int j = 0; j < 4; j++) { + b_smem[exact_div(bi * n * 8 * 4 * 4, 32) + bj * 8 * 4 * 4 + tj * 4 * 4 + 4 * k + j] = b_gmem[( + 4 * bkIdx + k) * n + 32 * bj + 4 * tj + j]; + } + } + } + for (int ti = 0; ti < 4; ti++) { + for (int tj = 0; tj < 8; tj++) { + for (int k = 0; k < 4; k++) { + float* const a_regs = (float*) malloc(8 * sizeof(float)); + for (int i = 0; i < 8; i++) { + a_regs[i] = a_smem[exact_div(bi * n * 4 * 4 * 8, 32) + bj * 4 * 4 * 8 + ti * 4 * 8 + 8 * k + i]; + } + float* const b_regs = (float*) malloc(4 * sizeof(float)); + for (int j = 0; j < 4; j++) { + b_regs[j] = b_smem[exact_div(bi * n * 8 * 4 * 4, 32) + bj * 8 * 4 * 4 + tj * 4 * 4 + 4 * k + j]; + } + for (int i = 0; i < 8; i++) { + for (int j = 0; j < 4; j++) { + sum[ti * 8 * 8 * 4 + tj * 8 * 4 + 4 * i + j] += a_regs[i] * b_regs[j]; + } + } + free(b_regs); + free(a_regs); + } + } + } + } + for (int ti = 0; ti < 4; ti++) { + for (int tj = 0; tj < 8; tj++) { + for (int i = 0; i < 8; i++) { + for (int j = 0; j < 4; j++) { + c_gmem[(32 * bi + 8 * ti + i) * n + 32 * bj + 4 * tj + j] = sum[ti * 8 * 8 * 4 + tj * 8 * 4 + 4 * i + j]; + } + } + } + } + free(sum); + } + } + free(b_smem); + free(a_smem); + free(b_gmem); + free(a_gmem); + for (int i1 = 0; i1 < m; i1++) { + for (int i2 = 0; i2 < n; i2++) { + c[i1 * n + i2] = c_gmem[i1 * n + i2]; + } + } + free(c_gmem); +} diff --git a/case_studies/gpu/matmul/matmul_exp.cpp b/case_studies/gpu/matmul/matmul_exp.cpp index 7475c8ef0..d1e390340 100644 --- a/case_studies/gpu/matmul/matmul_exp.cpp +++ b/case_studies/gpu/matmul/matmul_exp.cpp @@ -1,9 +1,6 @@ +#include #include - - - - const int bm = 32; const int bn = 32; @@ -14,95 +11,1059 @@ const int tn = 4; const int tm = 8; - void mm (float* c, float* a, float* b, int m, int n, int p) { - float* const c_gmem = (float*) malloc(m * n * sizeof(float)); - float* const a_gmem = (float*) malloc(m * p * sizeof(float)); - for (int i1 = 0; i1 < m; i1++) { - for (int i2 = 0; i2 < p; i2++) { - a_gmem[i1 * p + i2] = a[i1 * p + i2]; - } - } - float* const b_gmem = (float*) malloc(n * p * sizeof(float)); - for (int i1 = 0; i1 < p; i1++) { - for (int i2 = 0; i2 < n; i2++) { - b_gmem[i1 * n + i2] = b[i1 * n + i2]; - } - } - float* const a_smem = (float*) malloc(exact_div(4 * 4 * 8 * m * n, (32 * 32 - )) * sizeof(float)); - float* const b_smem = (float*) malloc(exact_div(8 * 4 * 4 * m * n, (32 * 32 - )) * sizeof(float)); - for (int bi = 0; bi < exact_div(m, 32); bi++) { - for (int bj = 0; bj < exact_div(n, 32); bj++) { - float* const sum = (float*) malloc(4 * 8 * 8 * 4 * sizeof(float)); - for (int ti = 0; ti < 4; ti++) { - for (int tj = 0; tj < 8; tj++) { - for (int i = 0; i < 8; i++) { - for (int j = 0; j < 4; j++) { - sum[ti * 8 * 8 * 4 + tj * 8 * 4 + 4 * i + j] = 0.f; +__ghost(to_prove, + "P := (MSIZE2(exact_div(32, 8), exact_div(32, 4)) = MSIZE2(4, 8))"); + +__ghost(to_prove, "P := (MSIZE2(4, 8) = MSIZE2(8, 4))"); + +__ghost(to_prove, "P := (MSIZE2(8, 4) = MSIZE2(4, 8))"); + +__ghost(to_prove, + "P := (MSIZE2(4, 8) = MSIZE2(exact_div(32, 8), exact_div(32, 4)))"); + +__ghost(to_prove, + "P := (MSIZE2(8, 4) = MSIZE2(exact_div(32, 8), exact_div(32, 4)))"); + +__ghost(to_prove, + "P := (MSIZE2(exact_div(32, 8), exact_div(32, 4)) = MSIZE2(8, 4))"); + +__ghost(assert_inhabited, "x := arbitrary(int * (int -> float) -> float)", + "reduce_sum <- x"); + +__ghost(assert_prop, + "proof := admit(forall (f: int -> float) -> (0.f =. reduce_sum(0, f)))", + "reduce_sum_empty <- proof"); + +__ghost(assert_prop, + "proof := admit(forall (n: int) (f: int -> float) (_: (n >= 0)) -> " + "(reduce_sum(n, f) +. f(n) =. reduce_sum(n + 1, f)))", + "reduce_sum_add_right <- proof"); + +__ghost(define, + "x := fun (A: int * int -> float) (B: int * int -> float) (p: int) -> " + "fun (i: int) (j: int) -> reduce_sum(p, fun k -> A(i, k) *. B(k, j))", + "matmul <- x"); + +void mm(float* c, float* a, float* b, int m, int n, int p) { + __requires("A: int * int -> float"); + __requires("B: int * int -> float"); + __requires("(m >= 0)"); + __requires("(n >= 0)"); + __requires("(p >= 0)"); + __preserves("HostCtx"); + __writes("c ~> Matrix2(m, n, matmul(A, B, p))"); + __reads("a ~> Matrix2(m, p, A)"); + __reads("b ~> Matrix2(p, n, B)"); + __ghost(to_prove, "P := (exact_div(m, 32) >= 0)"); + __ghost(to_prove, "P := (exact_div(n, 32) >= 0)"); + float* const c_gmem = __gmem_malloc2(m, n); + __with("T := float"); + __ghost([&]() { + __preserves("c_gmem ~> UninitMatrix2Of(m, n, GMem)"); + __admitted(); + __with("justif := shift_groups"); + }); + float* const a_gmem = __gmem_malloc2(m, p); + __with("T := float"); + __ghost([&]() { + __preserves("a_gmem ~> UninitMatrix2Of(m, p, GMem)"); + __admitted(); + __with("justif := shift_groups"); + }); + memcpy_host_to_device2(a_gmem, a, m, p); + float* const b_gmem = __gmem_malloc2(p, n); + __with("T := float"); + __ghost([&]() { + __preserves("b_gmem ~> UninitMatrix2Of(p, n, GMem)"); + __admitted(); + __with("justif := shift_groups"); + }); + memcpy_host_to_device2(b_gmem, b, p, n); + __ghost(assert_prop, "P := (m = exact_div(m, 32) * 32)", + "tile_div_check_i <- proof"); + __ghost(tile_divides, + "div_check := tile_div_check_i, items := fun (i: int) -> for j in " + "0..n -> &c_gmem[MINDEX2(m, n, i, j)] ~> UninitCellOf(GMem)"); + { + kernel_launch( + MSIZE2(exact_div(m, 32), exact_div(n, 32)), + MSIZE2(exact_div(32, 8), exact_div(32, 4)), + sizeof(float) * (4 * 4 * 8) + (sizeof(float) * (8 * 4 * 4) + 0)); + /*@kernel_body*/ {} /*kernel_body@*/ + __ghost(take_smem_token, "tok_sz := sizeof(float) * (4 * 4 * 8)"); + __ghost(take_smem_token, "tok_sz := sizeof(float) * (8 * 4 * 4)"); + float* const a_smem = __smem_malloc3(4, 4, 8); + __with("T := float"); + __ghost(assume, + "P := (MSIZE2(exact_div(m, 32), exact_div(n, 32)) = exact_div(m, " + "32) * (exact_div(n, 32)))"); + __ghost(rewrite_linear, + "from := MSIZE2(exact_div(m, 32), exact_div(n, 32)), to := " + "exact_div(m, 32) * (exact_div(n, 32)), inside := fun (sz: int) -> " + "desync_for i in ..sz -> for i1 in 0..4 -> for i2 in 0..4 -> for " + "i3 in 0..8 -> &a_smem[MINDEX4(sz, 4, 4, 8, DMINDEX1(sz, i), i1, " + "i2, i3)] ~> UninitCellOf(SMem)"); + __ghost(desync_tile_divides, + "items := fun (di: int) -> for i1 in 0..4 -> for i2 in 0..4 -> for " + "i3 in 0..8 -> &a_smem[MINDEX4(exact_div(m, 32) * (exact_div(n, " + "32)), 4, 4, 8, DMINDEX1(exact_div(m, 32) * (exact_div(n, 32)), " + "di), i1, i2, i3)] ~> UninitCellOf(SMem), div_check := " + "eq_refl(exact_div(m, 32) * (exact_div(n, 32))), tile_count := " + "exact_div(m, 32), tile_size := exact_div(n, 32)"); + __ghost( + dmindex2_untile, + "H := fun (f: int * int -> int) -> desync_for di1 in ..exact_div(m, " + "32) -> desync_for di2 in ..exact_div(n, 32) -> for i1 in 0..4 -> for " + "i2 in 0..4 -> for i3 in 0..8 -> &a_smem[MINDEX4(exact_div(m, 32) * " + "(exact_div(n, 32)), 4, 4, 8, f(di1, di2), i1, i2, i3)] ~> " + "UninitCellOf(SMem), n1 := exact_div(m, 32), n2 := exact_div(n, 32)"); + float* const b_smem = __smem_malloc3(8, 4, 4); + __with("T := float"); + __ghost(assume, + "P := (MSIZE2(exact_div(m, 32), exact_div(n, 32)) = exact_div(m, " + "32) * (exact_div(n, 32)))"); + __ghost(rewrite_linear, + "from := MSIZE2(exact_div(m, 32), exact_div(n, 32)), to := " + "exact_div(m, 32) * (exact_div(n, 32)), inside := fun (sz: int) -> " + "desync_for i in ..sz -> for i1 in 0..8 -> for i2 in 0..4 -> for " + "i3 in 0..4 -> &b_smem[MINDEX4(sz, 8, 4, 4, DMINDEX1(sz, i), i1, " + "i2, i3)] ~> UninitCellOf(SMem)"); + __ghost(desync_tile_divides, + "items := fun (di: int) -> for i1 in 0..8 -> for i2 in 0..4 -> for " + "i3 in 0..4 -> &b_smem[MINDEX4(exact_div(m, 32) * (exact_div(n, " + "32)), 8, 4, 4, DMINDEX1(exact_div(m, 32) * (exact_div(n, 32)), " + "di), i1, i2, i3)] ~> UninitCellOf(SMem), div_check := " + "eq_refl(exact_div(m, 32) * (exact_div(n, 32))), tile_count := " + "exact_div(m, 32), tile_size := exact_div(n, 32)"); + __ghost( + dmindex2_untile, + "H := fun (f: int * int -> int) -> desync_for di1 in ..exact_div(m, " + "32) -> desync_for di2 in ..exact_div(n, 32) -> for i1 in 0..8 -> for " + "i2 in 0..4 -> for i3 in 0..4 -> &b_smem[MINDEX4(exact_div(m, 32) * " + "(exact_div(n, 32)), 8, 4, 4, f(di1, di2), i1, i2, i3)] ~> " + "UninitCellOf(SMem), n1 := exact_div(m, 32), n2 := exact_div(n, 32)"); + for (int bi = 0; bi < exact_div(m, 32); bi++) { + __xconsumes( + "for i in 0..32 -> for j in 0..n -> &c_gmem[MINDEX2(m, n, bi * 32 + " + "i, j)] ~> UninitCellOf(GMem)"); + __xproduces( + "for bj in 0..(exact_div(n, 32)) -> for ti in 0..4 -> for j in 0..8 " + "-> for i in 0..8 -> for j68 in 0..4 -> &c_gmem[MINDEX2(m, n, bi * " + "32 + (ti * 8 + i), bj * 32 + (j * 4 + j68))] ~> UninitCellOf(GMem)"); + __ghost(assert_prop, "P := (32 = 4 * 8)", "tile_div_check_i1 <- proof"); + { + __ghost(tile_divides, + "div_check := tile_div_check_i1, items := fun (i: int) -> for " + "j in 0..n -> &c_gmem[MINDEX2(m, n, bi * 32 + i, j)] ~> " + "UninitCellOf(GMem)"); + for (int ti = 0; ti < 4; ti++) { + __xconsumes( + "for i in 0..8 -> for j in 0..n -> &c_gmem[MINDEX2(m, n, bi * 32 " + "+ (ti * 8 + i), j)] ~> UninitCellOf(GMem)"); + __xproduces( + "for j in 0..(exact_div(n, 32)) -> for i in 0..8 -> for j32 in " + "0..32 -> &c_gmem[MINDEX2(m, n, bi * 32 + (ti * 8 + i), j * 32 + " + "j32)] ~> UninitCellOf(GMem)"); + for (int i = 0; i < 8; i++) { + __xconsumes( + "for j in 0..n -> &c_gmem[MINDEX2(m, n, bi * 32 + (ti * 8 + " + "i), j)] ~> UninitCellOf(GMem)"); + __xproduces( + "for bi8 in 0..(exact_div(n, 32)) -> for i9 in 0..32 -> " + "&c_gmem[MINDEX2(m, n, bi * 32 + (ti * 8 + i), bi8 * 32 + i9)] " + "~> UninitCellOf(GMem)"); + __ghost(assert_prop, "P := (n = exact_div(n, 32) * 32)", + "tile_div_check_j <- proof"); + __ghost(tile_divides, + "div_check := tile_div_check_j, items := fun (j: int) -> " + "&c_gmem[MINDEX2(m, n, bi * 32 + (ti * 8 + i), j)] ~> " + "UninitCellOf(GMem)"); + } + __ghost(swap_groups, + "outer_range := 0..8, inner_range := 0..(exact_div(n, 32)), " + "items := fun (i: int) (bj: int) -> for j in 0..32 -> " + "&c_gmem[MINDEX2(m, n, bi * 32 + (ti * 8 + i), bj * 32 + j)] " + "~> UninitCellOf(GMem)"); + } + __ghost(swap_groups, + "outer_range := 0..4, inner_range := 0..(exact_div(n, 32)), " + "items := fun (ti: int) (bj: int) -> for i in 0..8 -> for j in " + "0..32 -> &c_gmem[MINDEX2(m, n, bi * 32 + (ti * 8 + i), bj * " + "32 + j)] ~> UninitCellOf(GMem)"); + for (int bj = 0; bj < exact_div(n, 32); bj++) { + __xconsumes( + "for ti in 0..4 -> for i in 0..8 -> for j in 0..32 -> " + "&c_gmem[MINDEX2(m, n, bi * 32 + (ti * 8 + i), bj * 32 + j)] ~> " + "UninitCellOf(GMem)"); + __xproduces( + "for ti in 0..4 -> for j in 0..8 -> for i in 0..8 -> for j68 in " + "0..4 -> &c_gmem[MINDEX2(m, n, bi * 32 + (ti * 8 + i), bj * 32 + " + "(j * 4 + j68))] ~> UninitCellOf(GMem)"); + for (int ti = 0; ti < 4; ti++) { + __xconsumes( + "for i in 0..8 -> for j in 0..32 -> &c_gmem[MINDEX2(m, n, bi * " + "32 + (ti * 8 + i), bj * 32 + j)] ~> UninitCellOf(GMem)"); + __xproduces( + "for j in 0..8 -> for i in 0..8 -> for j68 in 0..4 -> " + "&c_gmem[MINDEX2(m, n, bi * 32 + (ti * 8 + i), bj * 32 + (j * " + "4 + j68))] ~> UninitCellOf(GMem)"); + { + for (int i = 0; i < 8; i++) { + __xconsumes( + "for j in 0..32 -> &c_gmem[MINDEX2(m, n, bi * 32 + (ti * 8 " + "+ i), bj * 32 + j)] ~> UninitCellOf(GMem)"); + __xproduces( + "for bi15 in 0..8 -> for i16 in 0..4 -> &c_gmem[MINDEX2(m, " + "n, bi * 32 + (ti * 8 + i), bj * 32 + (bi15 * 4 + i16))] " + "~> UninitCellOf(GMem)"); + __ghost(assert_prop, "P := (32 = 8 * 4)", + "tile_div_check_j2 <- proof"); + __ghost(tile_divides, + "div_check := tile_div_check_j2, items := fun (j: int) " + "-> &c_gmem[MINDEX2(m, n, bi * 32 + (ti * 8 + i), bj * " + "32 + j)] ~> UninitCellOf(GMem)"); + } + __ghost(swap_groups, + "outer_range := 0..8, inner_range := 0..8, items := fun " + "(i: int) (tj: int) -> for j in 0..4 -> " + "&c_gmem[MINDEX2(m, n, bi * 32 + (ti * 8 + i), bj * 32 + " + "(tj * 4 + j))] ~> UninitCellOf(GMem)"); } } } } - for (int bkIdx = 0; bkIdx < exact_div(p, 4); bkIdx++) { - for (int ti = 0; ti < 4; ti++) { - for (int k = 0; k < 4; k++) { - for (int i = 0; i < 8; i++) { - a_smem[exact_div(bi * n * 4 * 4 * 8, 32) + bj * 4 * 4 * 8 + ti * 4 * 8 + 8 * k + i] = a_gmem[( - 32 * bi + 8 * ti + i) * p + 4 * bkIdx + k]; + } + __ghost(assume, + "P := (MSIZE2(exact_div(m, 32), exact_div(n, 32)) * " + "MSIZE2(exact_div(32, 8), exact_div(32, 4)) = MSIZE4(exact_div(m, " + "32), exact_div(n, 32), exact_div(32, 8), exact_div(32, 4)))"); + kernel_setup_end(); + __with( + "grid_sz := MSIZE4(exact_div(m, 32), exact_div(n, 32), exact_div(32, " + "8), exact_div(32, 4))"); + __threadfor; + for (int bi = 0; bi < exact_div(m, 32); bi++) { + __sreads("a_gmem ~> Matrix2Of(m, p, GMem, A)"); + __sreads("b_gmem ~> Matrix2Of(p, n, GMem, B)"); + __xpreserves( + "desync_for _v62 in ..exact_div(n, 32) -> for _v63 in 0..8 -> for " + "_v64 in 0..4 -> for _v65 in 0..4 -> &b_smem[MINDEX4(exact_div(m, " + "32) * (exact_div(n, 32)), 8, 4, 4, DMINDEX2(exact_div(m, 32), " + "exact_div(n, 32), bi, _v62), _v63, _v64, _v65)] ~> " + "UninitCellOf(SMem)"); + __xpreserves( + "desync_for _v55 in ..exact_div(n, 32) -> for _v56 in 0..4 -> for " + "_v57 in 0..4 -> for _v58 in 0..8 -> &a_smem[MINDEX4(exact_div(m, " + "32) * (exact_div(n, 32)), 4, 4, 8, DMINDEX2(exact_div(m, 32), " + "exact_div(n, 32), bi, _v55), _v56, _v57, _v58)] ~> " + "UninitCellOf(SMem)"); + __xwrites( + "desync_for bj in ..exact_div(n, 32) -> desync_for ti in ..4 -> " + "desync_for tj in ..8 -> for i in 0..8 -> for j in 0..4 -> " + "&c_gmem[MINDEX2(m, n, bi * 32 + (ti * 8 + i), bj * 32 + (tj * 4 + " + "j))] ~~>[GMem] reduce_sum(p, fun k -> A(bi * 32 + (ti * 8 + i), k) " + "*. B(k, bj * 32 + (tj * 4 + j)))"); + __ghost(assert_prop, "P := (32 = 4 * 8)", "tile_div_check_i170 <- proof"); + __threadfor; + for (int bj = 0; bj < exact_div(n, 32); bj++) { + __sreads("a_gmem ~> Matrix2Of(m, p, GMem, A)"); + __sreads("b_gmem ~> Matrix2Of(p, n, GMem, B)"); + __xpreserves( + "for _v59 in 0..8 -> for _v60 in 0..4 -> for _v61 in 0..4 -> " + "&b_smem[MINDEX4(exact_div(m, 32) * (exact_div(n, 32)), 8, 4, 4, " + "DMINDEX2(exact_div(m, 32), exact_div(n, 32), bi, bj), _v59, _v60, " + "_v61)] ~> UninitCellOf(SMem)"); + __xpreserves( + "for _v52 in 0..4 -> for _v53 in 0..4 -> for _v54 in 0..8 -> " + "&a_smem[MINDEX4(exact_div(m, 32) * (exact_div(n, 32)), 4, 4, 8, " + "DMINDEX2(exact_div(m, 32), exact_div(n, 32), bi, bj), _v52, _v53, " + "_v54)] ~> UninitCellOf(SMem)"); + __xwrites( + "desync_for ti in ..4 -> desync_for tj in ..8 -> for i in 0..8 -> " + "for j in 0..4 -> &c_gmem[MINDEX2(m, n, bi * 32 + (ti * 8 + i), bj " + "* 32 + (tj * 4 + j))] ~~>[GMem] reduce_sum(p, fun k -> A(bi * 32 " + "+ (ti * 8 + i), k) *. B(k, bj * 32 + (tj * 4 + j)))"); + __ghost(rewrite_threadsctx_sz, + "from := MSIZE2(exact_div(32, 8), exact_div(32, 4)), to := " + "MSIZE2(4, 8)"); + float* const sum = __treg_ref_uninit2(8, 4); + __with("T := float"); + __ghost(assume, "P := (MSIZE2(4, 8) = 4 * 8)"); + __ghost(rewrite_linear, + "from := MSIZE2(4, 8), to := 4 * 8, inside := fun (sz: int) -> " + "desync_for i in ..sz -> for i1 in 0..8 -> for i2 in 0..4 -> " + "&sum[MINDEX3(sz, 8, 4, DMINDEX1(sz, i), i1, i2)] ~> " + "UninitCellOf(TReg)"); + __ghost(desync_tile_divides, + "items := fun (di: int) -> for i1 in 0..8 -> for i2 in 0..4 -> " + "&sum[MINDEX3(4 * 8, 8, 4, DMINDEX1(4 * 8, di), i1, i2)] ~> " + "UninitCellOf(TReg), div_check := eq_refl(4 * 8), tile_count " + ":= 4, tile_size := 8"); + __ghost(dmindex2_untile, + "H := fun (f: int * int -> int) -> desync_for di1 in ..4 -> " + "desync_for di2 in ..8 -> for i1 in 0..8 -> for i2 in 0..4 -> " + "&sum[MINDEX3(4 * 8, 8, 4, f(di1, di2), i1, i2)] ~> " + "UninitCellOf(TReg), n1 := 4, n2 := 8"); + __threadfor; + for (int ti = 0; ti < 4; ti++) { + __xwrites( + "desync_for tj in ..8 -> for i in 0..8 -> for j in 0..4 -> " + "&sum[MINDEX3(4 * 8, 8, 4, DMINDEX2(4, 8, ti, tj), i, j)] " + "~~>[TReg] reduce_sum(0 * 4, fun k0 -> A(bi * 32 + (ti * 8 + i), " + "k0) *. B(k0, bj * 32 + (tj * 4 + j)))"); + __threadfor; + for (int tj = 0; tj < 8; tj++) { + __xwrites( + "for i in 0..8 -> for j in 0..4 -> &sum[MINDEX3(4 * 8, 8, 4, " + "DMINDEX2(4, 8, ti, tj), i, j)] ~~>[TReg] reduce_sum(0 * 4, " + "fun k0 -> A(bi * 32 + (ti * 8 + i), k0) *. B(k0, bj * 32 + " + "(tj * 4 + j)))"); + for (int i = 0; i < 8; i++) { + __xwrites( + "for j in 0..4 -> &sum[MINDEX3(4 * 8, 8, 4, DMINDEX2(4, 8, " + "ti, tj), i, j)] ~~>[TReg] reduce_sum(0 * 4, fun k0 -> A(bi " + "* 32 + (ti * 8 + i), k0) *. B(k0, bj * 32 + (tj * 4 + j)))"); + for (int j = 0; j < 4; j++) { + __xwrites( + "&sum[MINDEX3(4 * 8, 8, 4, DMINDEX2(4, 8, ti, tj), i, j)] " + "~~>[TReg] reduce_sum(0 * 4, fun k0 -> A(bi * 32 + (ti * 8 " + "+ i), k0) *. B(k0, bj * 32 + (tj * 4 + j)))"); + __treg_set( + &sum[MINDEX3(4 * 8, 8, 4, DMINDEX2(4, 8, ti, tj), i, j)], + 0.f); + __ghost(rewrite_float_linear, + "inside := fun v -> &sum[MINDEX3(4 * 8, 8, 4, " + "DMINDEX2(4, 8, ti, tj), i, j)] ~~>[TReg] v, by := " + "reduce_sum_empty(fun k -> A(bi * 32 + (ti * 8 + i), " + "k) *. B(k, bj * 32 + (tj * 4 + j)))"); + __ghost( + rewrite_linear, + "inside := fun (k: int) -> &sum[MINDEX3(4 * 8, 8, 4, " + "DMINDEX2(4, 8, ti, tj), i, j)] ~~>[TReg] reduce_sum(k, " + "fun k0 -> A(bi * 32 + (ti * 8 + i), k0) *. B(k0, bj * 32 " + "+ (tj * 4 + j))), by := zero_mul_intro(4)"); + } } } } - for (int tj = 0; tj < 8; tj++) { - for (int k = 0; k < 4; k++) { - for (int j = 0; j < 4; j++) { - b_smem[exact_div(bi * n * 8 * 4 * 4, 32) + bj * 8 * 4 * 4 + tj * 4 * 4 + 4 * k + j] = b_gmem[( - 4 * bkIdx + k) * n + 32 * bj + 4 * tj + j]; + for (int bkIdx = 0; bkIdx < exact_div(p, 4); bkIdx++) { + __spreserves( + "ThreadsCtx(MINDEX3(exact_div(m, 32), exact_div(n, 32), 0, bi, " + "bj, 0)..+MSIZE2(4, 8))"); + __spreserves( + "for i1 in 0..8 -> for i2 in 0..4 -> for i3 in 0..4 -> " + "&b_smem[MINDEX4(exact_div(m, 32) * (exact_div(n, 32)), 8, 4, 4, " + "DMINDEX2(exact_div(m, 32), exact_div(n, 32), bi, bj), i1, i2, " + "i3)] ~> UninitCellOf(SMem)"); + __spreserves( + "for i1 in 0..4 -> for i2 in 0..4 -> for i3 in 0..8 -> " + "&a_smem[MINDEX4(exact_div(m, 32) * (exact_div(n, 32)), 4, 4, 8, " + "DMINDEX2(exact_div(m, 32), exact_div(n, 32), bi, bj), i1, i2, " + "i3)] ~> UninitCellOf(SMem)"); + __spreserves( + "desync_for ti in ..4 -> desync_for tj in ..8 -> for i in 0..8 " + "-> for j in 0..4 -> &sum[MINDEX3(4 * 8, 8, 4, DMINDEX2(4, 8, " + "ti, tj), i, j)] ~~>[TReg] reduce_sum(bkIdx * 4, fun k0 -> A(bi " + "* 32 + (ti * 8 + i), k0) *. B(k0, bj * 32 + (tj * 4 + j)))"); + __sreads("a_gmem ~> Matrix2Of(m, p, GMem, A)"); + __sreads("b_gmem ~> Matrix2Of(p, n, GMem, B)"); + __threadfor; + for (int ti = 0; ti < 4; ti++) { + __sreads("a_gmem ~> Matrix2Of(m, p, GMem, A)"); + __xconsumes( + "for k in 0..4 -> for i in 0..8 -> " + "&a_smem[MINDEX4(exact_div(m, 32) * (exact_div(n, 32)), 4, 4, " + "8, DMINDEX2(exact_div(m, 32), exact_div(n, 32), bi, bj), ti, " + "k, i)] ~> UninitCellOf(SMem)"); + __xproduces( + "for k in 0..4 -> desync_for i in ..8 -> " + "&a_smem[MINDEX4(exact_div(m, 32) * (exact_div(n, 32)), 4, 4, " + "8, DMINDEX2(exact_div(m, 32), exact_div(n, 32), bi, bj), ti, " + "k, i)] ~~>[SMem] A(bi * 32 + (ti * 8 + i), bkIdx * 4 + k)"); + for (int k = 0; k < 4; k++) { + __spreserves( + "ThreadsCtx(MINDEX4(exact_div(m, 32), exact_div(n, 32), 4, " + "0, bi, bj, ti, 0)..+MSIZE1(8))"); + __sreads("a_gmem ~> Matrix2Of(m, p, GMem, A)"); + __xconsumes( + "for i in 0..8 -> &a_smem[MINDEX4(exact_div(m, 32) * " + "(exact_div(n, 32)), 4, 4, 8, DMINDEX2(exact_div(m, 32), " + "exact_div(n, 32), bi, bj), ti, k, i)] ~> " + "UninitCellOf(SMem)"); + __xproduces( + "desync_for i in ..8 -> &a_smem[MINDEX4(exact_div(m, 32) * " + "(exact_div(n, 32)), 4, 4, 8, DMINDEX2(exact_div(m, 32), " + "exact_div(n, 32), bi, bj), ti, k, i)] ~~>[SMem] A(bi * 32 + " + "(ti * 8 + i), bkIdx * 4 + k)"); + __threadfor; + for (int i = 0; i < 8; i++) { + __sreads("a_gmem ~> Matrix2Of(m, p, GMem, A)"); + __xwrites( + "&a_smem[MINDEX4(exact_div(m, 32) * (exact_div(n, 32)), 4, " + "4, 8, DMINDEX2(exact_div(m, 32), exact_div(n, 32), bi, " + "bj), ti, k, i)] ~~>[SMem] A(bi * 32 + (ti * 8 + i), bkIdx " + "* 4 + k)"); + __ghost(assert_prop, "P := (p = exact_div(p, 4) * 4)", + "tile_div_check_k35 <- proof"); + __ghost(tiled_index_in_range, + "tile_index := bkIdx, index := k, div_check := " + "tile_div_check_k35"); + __ghost(tiled_index_in_range, + "tile_index := ti, index := i, div_check := " + "tile_div_check_i170"); + __ghost(tiled_index_in_range, + "tile_index := bi, index := ti * 8 + i, div_check := " + "tile_div_check_i"); + const __ghost_fn __ghost_pair_6 = + __ghost_begin(ro_matrix2_focus, + "matrix := a_gmem, i := bi * 32 + (ti * 8 + " + "i), j := bkIdx * 4 + k"); + __smem_set( + &a_smem[MINDEX4( + exact_div(m, 32) * (exact_div(n, 32)), 4, 4, 8, + DMINDEX2(exact_div(m, 32), exact_div(n, 32), bi, bj), + ti, k, i)], + __gmem_get(&a_gmem[MINDEX2(m, p, bi * 32 + (ti * 8 + i), + bkIdx * 4 + k)])); + __ghost_end(__ghost_pair_6); + } } } - } - for (int ti = 0; ti < 4; ti++) { - for (int tj = 0; tj < 8; tj++) { - for (int k = 0; k < 4; k++) { - float* const a_regs = (float*) malloc(8 * sizeof(float)); - for (int i = 0; i < 8; i++) { - a_regs[i] = a_smem[exact_div(bi * n * 4 * 4 * 8, 32) + bj * 4 * 4 * 8 + ti * 4 * 8 + 8 * k + i]; + __ghost(rewrite_threadsctx_sz, + "from := MSIZE2(4, 8), to := MSIZE2(8, 4)"); + __threadfor; + for (int tj = 0; tj < 8; tj++) { + __sreads("b_gmem ~> Matrix2Of(p, n, GMem, B)"); + __xconsumes( + "for k in 0..4 -> for j in 0..4 -> " + "&b_smem[MINDEX4(exact_div(m, 32) * (exact_div(n, 32)), 8, 4, " + "4, DMINDEX2(exact_div(m, 32), exact_div(n, 32), bi, bj), tj, " + "k, j)] ~> UninitCellOf(SMem)"); + __xproduces( + "desync_for k in ..4 -> for j in 0..4 -> " + "&b_smem[MINDEX4(exact_div(m, 32) * (exact_div(n, 32)), 8, 4, " + "4, DMINDEX2(exact_div(m, 32), exact_div(n, 32), bi, bj), tj, " + "k, j)] ~~>[SMem] B(bkIdx * 4 + k, bj * 32 + (tj * 4 + j))"); + __threadfor; + for (int k = 0; k < 4; k++) { + __sreads("b_gmem ~> Matrix2Of(p, n, GMem, B)"); + __xwrites( + "for j in 0..4 -> &b_smem[MINDEX4(exact_div(m, 32) * " + "(exact_div(n, 32)), 8, 4, 4, DMINDEX2(exact_div(m, 32), " + "exact_div(n, 32), bi, bj), tj, k, j)] ~~>[SMem] B(bkIdx * 4 " + "+ k, bj * 32 + (tj * 4 + j))"); + __ghost(assert_prop, "P := (p = exact_div(p, 4) * 4)", + "tile_div_check_k3542 <- proof"); + __ghost(tiled_index_in_range, + "tile_index := bkIdx, index := k, div_check := " + "tile_div_check_k3542"); + __ghost(assert_prop, "P := (n = exact_div(n, 32) * 32)", + "tile_div_check_j713222644 <- proof"); + __ghost(assert_prop, "P := (32 = 8 * 4)", + "tile_div_check_j214232743 <- proof"); + for (int j = 0; j < 4; j++) { + __sreads("b_gmem ~> Matrix2Of(p, n, GMem, B)"); + __xwrites( + "&b_smem[MINDEX4(exact_div(m, 32) * (exact_div(n, 32)), 8, " + "4, 4, DMINDEX2(exact_div(m, 32), exact_div(n, 32), bi, " + "bj), tj, k, j)] ~~>[SMem] B(bkIdx * 4 + k, bj * 32 + (tj " + "* 4 + j))"); + __ghost(tiled_index_in_range, + "tile_index := tj, index := j, div_check := " + "tile_div_check_j214232743"); + __ghost(tiled_index_in_range, + "tile_index := bj, index := tj * 4 + j, div_check := " + "tile_div_check_j713222644"); + const __ghost_fn __ghost_pair_9 = + __ghost_begin(ro_matrix2_focus, + "matrix := b_gmem, i := bkIdx * 4 + k, j := " + "bj * 32 + (tj * 4 + j)"); + __smem_set( + &b_smem[MINDEX4( + exact_div(m, 32) * (exact_div(n, 32)), 8, 4, 4, + DMINDEX2(exact_div(m, 32), exact_div(n, 32), bi, bj), + tj, k, j)], + __gmem_get(&b_gmem[MINDEX2(p, n, bkIdx * 4 + k, + bj * 32 + (tj * 4 + j))])); + __ghost_end(__ghost_pair_9); } - float* const b_regs = (float*) malloc(4 * sizeof(float)); - for (int j = 0; j < 4; j++) { - b_regs[j] = b_smem[exact_div(bi * n * 8 * 4 * 4, 32) + bj * 8 * 4 * 4 + tj * 4 * 4 + 4 * k + j]; + } + } + __ghost(rewrite_threadsctx_sz, + "from := MSIZE2(8, 4), to := MSIZE2(exact_div(32, 8), " + "exact_div(32, 4))"); + /*@sync1*/ __barrier_sequence; + { + blocksync(); + __with( + "H := desync_for tj in ..8 -> desync_for k in ..4 -> for j in " + "0..4 -> &b_smem[MINDEX4(exact_div(m, 32) * (exact_div(n, " + "32)), 8, 4, 4, DMINDEX2(exact_div(m, 32), exact_div(n, 32), " + "bi, bj), tj, k, j)] ~~>[SMem] B(bkIdx * 4 + k, bj * 32 + (tj " + "* 4 + j))"); + blocksync(); + __with( + "H := desync_for ti in ..4 -> for k in 0..4 -> desync_for i in " + "..8 -> &a_smem[MINDEX4(exact_div(m, 32) * (exact_div(n, 32)), " + "4, 4, 8, DMINDEX2(exact_div(m, 32), exact_div(n, 32), bi, " + "bj), ti, k, i)] ~~>[SMem] A(bi * 32 + (ti * 8 + i), bkIdx * 4 " + "+ k)"); + blocksync(); + __with( + "H := desync_for ti in ..4 -> desync_for tj in ..8 -> for i in " + "0..8 -> for j in 0..4 -> &c_gmem[MINDEX2(m, n, bi * 32 + (ti " + "* 8 + i), bj * 32 + (tj * 4 + j))] ~> UninitCellOf(GMem)"); + } /*sync1@*/ + __ghost(rewrite_threadsctx_sz, + "from := MSIZE2(exact_div(32, 8), exact_div(32, 4)), to := " + "MSIZE2(8, 4)"); + __ghost(rewrite_threadsctx_sz, + "from := MSIZE2(8, 4), to := MSIZE2(4, 8)"); + __threadfor; + for (int ti = 0; ti < 4; ti++) { + __sreads( + "for ti in 0..4 -> for k in 0..4 -> for i in 0..8 -> " + "&a_smem[MINDEX4(exact_div(m, 32) * (exact_div(n, 32)), 4, 4, " + "8, DMINDEX2(exact_div(m, 32), exact_div(n, 32), bi, bj), ti, " + "k, i)] ~~>[SMem] A(bi * 32 + (ti * 8 + i), bkIdx * 4 + k)"); + __sreads( + "for tj in 0..8 -> for k in 0..4 -> for j in 0..4 -> " + "&b_smem[MINDEX4(exact_div(m, 32) * (exact_div(n, 32)), 8, 4, " + "4, DMINDEX2(exact_div(m, 32), exact_div(n, 32), bi, bj), tj, " + "k, j)] ~~>[SMem] B(bkIdx * 4 + k, bj * 32 + (tj * 4 + j))"); + __xconsumes( + "desync_for tj in ..8 -> for i in 0..8 -> for j in 0..4 -> " + "&sum[MINDEX3(4 * 8, 8, 4, DMINDEX2(4, 8, ti, tj), i, j)] " + "~~>[TReg] reduce_sum(bkIdx * 4, fun k0 -> A(bi * 32 + (ti * 8 " + "+ i), k0) *. B(k0, bj * 32 + (tj * 4 + j)))"); + __xproduces( + "desync_for tj in ..8 -> for i in 0..8 -> for j in 0..4 -> " + "&sum[MINDEX3(4 * 8, 8, 4, DMINDEX2(4, 8, ti, tj), i, j)] " + "~~>[TReg] reduce_sum((bkIdx + 1) * 4, fun k0 -> A(bi * 32 + " + "(ti * 8 + i), k0) *. B(k0, bj * 32 + (tj * 4 + j)))"); + const __ghost_fn __ghost_pair_12 = __ghost_begin( + ro_group_focus, + "i := ti, items := fun (ti: int) -> for k in 0..4 -> for i in " + "0..8 -> &a_smem[MINDEX4(exact_div(m, 32) * (exact_div(n, " + "32)), 4, 4, 8, DMINDEX2(exact_div(m, 32), exact_div(n, 32), " + "bi, bj), ti, k, i)] ~~>[SMem] A(bi * 32 + (ti * 8 + i), bkIdx " + "* 4 + k)"); + __threadfor; + for (int tj = 0; tj < 8; tj++) { + __sreads( + "for tj in 0..8 -> for k in 0..4 -> for j in 0..4 -> " + "&b_smem[MINDEX4(exact_div(m, 32) * (exact_div(n, 32)), 8, " + "4, 4, DMINDEX2(exact_div(m, 32), exact_div(n, 32), bi, bj), " + "tj, k, j)] ~~>[SMem] B(bkIdx * 4 + k, bj * 32 + (tj * 4 + " + "j))"); + __sreads( + "for k in 0..4 -> for i in 0..8 -> " + "&a_smem[MINDEX4(exact_div(m, 32) * (exact_div(n, 32)), 4, " + "4, 8, DMINDEX2(exact_div(m, 32), exact_div(n, 32), bi, bj), " + "ti, k, i)] ~~>[SMem] A(bi * 32 + (ti * 8 + i), bkIdx * 4 + " + "k)"); + __xconsumes( + "for i in 0..8 -> for j in 0..4 -> &sum[MINDEX3(4 * 8, 8, 4, " + "DMINDEX2(4, 8, ti, tj), i, j)] ~~>[TReg] reduce_sum(bkIdx * " + "4, fun k0 -> A(bi * 32 + (ti * 8 + i), k0) *. B(k0, bj * 32 " + "+ (tj * 4 + j)))"); + __xproduces( + "for i in 0..8 -> for j in 0..4 -> &sum[MINDEX3(4 * 8, 8, 4, " + "DMINDEX2(4, 8, ti, tj), i, j)] ~~>[TReg] reduce_sum((bkIdx " + "+ 1) * 4, fun k0 -> A(bi * 32 + (ti * 8 + i), k0) *. B(k0, " + "bj * 32 + (tj * 4 + j)))"); + const __ghost_fn __ghost_pair_11 = __ghost_begin( + ro_group_focus, + "i := tj, items := fun (tj: int) -> for k in 0..4 -> for j " + "in 0..4 -> &b_smem[MINDEX4(exact_div(m, 32) * (exact_div(n, " + "32)), 8, 4, 4, DMINDEX2(exact_div(m, 32), exact_div(n, 32), " + "bi, bj), tj, k, j)] ~~>[SMem] B(bkIdx * 4 + k, bj * 32 + " + "(tj * 4 + j))"); + for (int i = 0; i < 8; i++) { + __xconsumes( + "for j in 0..4 -> &sum[MINDEX3(4 * 8, 8, 4, DMINDEX2(4, 8, " + "ti, tj), i, j)] ~~>[TReg] reduce_sum(bkIdx * 4, fun k0 -> " + "A(bi * 32 + (ti * 8 + i), k0) *. B(k0, bj * 32 + (tj * 4 " + "+ j)))"); + __xproduces( + "for j in 0..4 -> &sum[MINDEX3(4 * 8, 8, 4, DMINDEX2(4, 8, " + "ti, tj), i, j)] ~~>[TReg] reduce_sum(bkIdx * 4 + 0, fun " + "k0 -> A(bi * 32 + (ti * 8 + i), k0) *. B(k0, bj * 32 + " + "(tj * 4 + j)))"); + for (int j = 0; j < 4; j++) { + __xconsumes( + "&sum[MINDEX3(4 * 8, 8, 4, DMINDEX2(4, 8, ti, tj), i, " + "j)] ~~>[TReg] reduce_sum(bkIdx * 4, fun k0 -> A(bi * 32 " + "+ (ti * 8 + i), k0) *. B(k0, bj * 32 + (tj * 4 + j)))"); + __xproduces( + "&sum[MINDEX3(4 * 8, 8, 4, DMINDEX2(4, 8, ti, tj), i, " + "j)] ~~>[TReg] reduce_sum(bkIdx * 4 + 0, fun k0 -> A(bi " + "* 32 + (ti * 8 + i), k0) *. B(k0, bj * 32 + (tj * 4 + " + "j)))"); + __ghost( + rewrite_linear, + "inside := fun (k: int) -> &sum[MINDEX3(4 * 8, 8, 4, " + "DMINDEX2(4, 8, ti, tj), i, j)] ~~>[TReg] reduce_sum(k, " + "fun k0 -> A(bi * 32 + (ti * 8 + i), k0) *. B(k0, bj * " + "32 + (tj * 4 + j))), by := plus_zero_intro(bkIdx * 4)"); + } } - for (int i = 0; i < 8; i++) { - for (int j = 0; j < 4; j++) { - sum[ti * 8 * 8 * 4 + tj * 8 * 4 + 4 * i + j] += a_regs[i] * b_regs[j]; + for (int k = 0; k < 4; k++) { + __spreserves( + "for i in 0..8 -> for j in 0..4 -> &sum[MINDEX3(4 * 8, 8, " + "4, DMINDEX2(4, 8, ti, tj), i, j)] ~~>[TReg] " + "reduce_sum(bkIdx * 4 + k, fun k0 -> A(bi * 32 + (ti * 8 + " + "i), k0) *. B(k0, bj * 32 + (tj * 4 + j)))"); + __xreads( + "for i in 0..8 -> &a_smem[MINDEX4(exact_div(m, 32) * " + "(exact_div(n, 32)), 4, 4, 8, DMINDEX2(exact_div(m, 32), " + "exact_div(n, 32), bi, bj), ti, k, i)] ~~>[SMem] A(bi * 32 " + "+ (ti * 8 + i), bkIdx * 4 + k)"); + __xreads( + "for j in 0..4 -> &b_smem[MINDEX4(exact_div(m, 32) * " + "(exact_div(n, 32)), 8, 4, 4, DMINDEX2(exact_div(m, 32), " + "exact_div(n, 32), bi, bj), tj, k, j)] ~~>[SMem] B(bkIdx * " + "4 + k, bj * 32 + (tj * 4 + j))"); + __ghost(assert_prop, "P := (p = exact_div(p, 4) * 4)", + "tile_div_check_k354251 <- proof"); + __ghost(tiled_index_in_range, + "tile_index := bkIdx, index := k, div_check := " + "tile_div_check_k354251"); + __ghost(assert_prop, "P := (n = exact_div(n, 32) * 32)", + "tile_div_check_j71322264450 <- proof"); + __ghost(assert_prop, "P := (32 = 8 * 4)", + "tile_div_check_j21423274349 <- proof"); + float* const a_regs = __treg_ref_uninit1_s(8); + __with("T := float"); + for (int i = 0; i < 8; i++) { + __xwrites( + "&a_regs[MINDEX1(8, i)] ~~>[TReg] A(bi * 32 + (ti * 8 + " + "i), bkIdx * 4 + k)"); + __xreads( + "&a_smem[MINDEX4(exact_div(m, 32) * (exact_div(n, 32)), " + "4, 4, 8, DMINDEX2(exact_div(m, 32), exact_div(n, 32), " + "bi, bj), ti, k, i)] ~~>[SMem] A(bi * 32 + (ti * 8 + i), " + "bkIdx * 4 + k)"); + __treg_set( + &a_regs[MINDEX1(8, i)], + __smem_get(&a_smem[MINDEX4( + exact_div(m, 32) * (exact_div(n, 32)), 4, 4, 8, + DMINDEX2(exact_div(m, 32), exact_div(n, 32), bi, bj), + ti, k, i)])); + } + float* const b_regs = __treg_ref_uninit1_s(4); + __with("T := float"); + for (int j = 0; j < 4; j++) { + __xwrites( + "&b_regs[MINDEX1(4, j)] ~~>[TReg] B(bkIdx * 4 + k, bj * " + "32 + (tj * 4 + j))"); + __xreads( + "&b_smem[MINDEX4(exact_div(m, 32) * (exact_div(n, 32)), " + "8, 4, 4, DMINDEX2(exact_div(m, 32), exact_div(n, 32), " + "bi, bj), tj, k, j)] ~~>[SMem] B(bkIdx * 4 + k, bj * 32 " + "+ (tj * 4 + j))"); + __treg_set( + &b_regs[MINDEX1(4, j)], + __smem_get(&b_smem[MINDEX4( + exact_div(m, 32) * (exact_div(n, 32)), 8, 4, 4, + DMINDEX2(exact_div(m, 32), exact_div(n, 32), bi, bj), + tj, k, j)])); + } + for (int i = 0; i < 8; i++) { + __sreads( + "for j in 0..4 -> &b_regs[MINDEX1(4, j)] ~~>[TReg] " + "B(bkIdx * 4 + k, bj * 32 + (tj * 4 + j))"); + __xconsumes( + "for j in 0..4 -> &sum[MINDEX3(4 * 8, 8, 4, DMINDEX2(4, " + "8, ti, tj), i, j)] ~~>[TReg] reduce_sum(bkIdx * 4 + k, " + "fun k0 -> A(bi * 32 + (ti * 8 + i), k0) *. B(k0, bj * " + "32 + (tj * 4 + j)))"); + __xproduces( + "for j in 0..4 -> &sum[MINDEX3(4 * 8, 8, 4, DMINDEX2(4, " + "8, ti, tj), i, j)] ~~>[TReg] reduce_sum(bkIdx * 4 + (k " + "+ 1), fun k0 -> A(bi * 32 + (ti * 8 + i), k0) *. B(k0, " + "bj * 32 + (tj * 4 + j)))"); + __xreads( + "&a_regs[MINDEX1(8, i)] ~~>[TReg] A(bi * 32 + (ti * 8 + " + "i), bkIdx * 4 + k)"); + for (int j = 0; j < 4; j++) { + __sreads( + "&a_regs[MINDEX1(8, i)] ~~>[TReg] A(bi * 32 + (ti * 8 " + "+ i), bkIdx * 4 + k)"); + __xconsumes( + "&sum[MINDEX3(4 * 8, 8, 4, DMINDEX2(4, 8, ti, tj), i, " + "j)] ~~>[TReg] reduce_sum(bkIdx * 4 + k, fun k0 -> " + "A(bi * 32 + (ti * 8 + i), k0) *. B(k0, bj * 32 + (tj " + "* 4 + j)))"); + __xproduces( + "&sum[MINDEX3(4 * 8, 8, 4, DMINDEX2(4, 8, ti, tj), i, " + "j)] ~~>[TReg] reduce_sum(bkIdx * 4 + (k + 1), fun k0 " + "-> A(bi * 32 + (ti * 8 + i), k0) *. B(k0, bj * 32 + " + "(tj * 4 + j)))"); + __xreads( + "&b_regs[MINDEX1(4, j)] ~~>[TReg] B(bkIdx * 4 + k, bj " + "* 32 + (tj * 4 + j))"); + __treg_set( + &sum[MINDEX3(4 * 8, 8, 4, DMINDEX2(4, 8, ti, tj), i, + j)], + __treg_get(&sum[MINDEX3( + 4 * 8, 8, 4, DMINDEX2(4, 8, ti, tj), i, j)]) + + __treg_get(&a_regs[MINDEX1(8, i)]) * + __treg_get(&b_regs[MINDEX1(4, j)])); + __ghost(in_range_bounds, "x := bkIdx * 4 + k", + "k_ge_04866 <- lower_bound, #_3567 <- upper_bound"); + __ghost(rewrite_float_linear, + "inside := fun v -> &sum[MINDEX3(4 * 8, 8, 4, " + "DMINDEX2(4, 8, ti, tj), i, j)] ~~>[TReg] v, by := " + "reduce_sum_add_right(bkIdx * 4 + k, fun k -> A(bi " + "* 32 + (ti * 8 + i), k) *. B(k, bj * 32 + (tj * 4 " + "+ j)), k_ge_04866)"); + __ghost(rewrite_linear, + "inside := fun (k: int) -> &sum[MINDEX3(4 * 8, 8, " + "4, DMINDEX2(4, 8, ti, tj), i, j)] ~~>[TReg] " + "reduce_sum(k, fun k0 -> A(bi * 32 + (ti * 8 + i), " + "k0) *. B(k0, bj * 32 + (tj * 4 + j))), by := " + "add_assoc_right(bkIdx * 4, k, 1)"); + } } } - free(b_regs); - free(a_regs); + for (int i = 0; i < 8; i++) { + __xconsumes( + "for j in 0..4 -> &sum[MINDEX3(4 * 8, 8, 4, DMINDEX2(4, 8, " + "ti, tj), i, j)] ~~>[TReg] reduce_sum(bkIdx * 4 + 4, fun " + "k0 -> A(bi * 32 + (ti * 8 + i), k0) *. B(k0, bj * 32 + " + "(tj * 4 + j)))"); + __xproduces( + "for j in 0..4 -> &sum[MINDEX3(4 * 8, 8, 4, DMINDEX2(4, 8, " + "ti, tj), i, j)] ~~>[TReg] reduce_sum((bkIdx + 1) * 4, fun " + "k0 -> A(bi * 32 + (ti * 8 + i), k0) *. B(k0, bj * 32 + " + "(tj * 4 + j)))"); + for (int j = 0; j < 4; j++) { + __xconsumes( + "&sum[MINDEX3(4 * 8, 8, 4, DMINDEX2(4, 8, ti, tj), i, " + "j)] ~~>[TReg] reduce_sum(bkIdx * 4 + 4, fun k0 -> A(bi " + "* 32 + (ti * 8 + i), k0) *. B(k0, bj * 32 + (tj * 4 + " + "j)))"); + __xproduces( + "&sum[MINDEX3(4 * 8, 8, 4, DMINDEX2(4, 8, ti, tj), i, " + "j)] ~~>[TReg] reduce_sum((bkIdx + 1) * 4, fun k0 -> " + "A(bi * 32 + (ti * 8 + i), k0) *. B(k0, bj * 32 + (tj * " + "4 + j)))"); + __ghost( + rewrite_linear, + "inside := fun (k: int) -> &sum[MINDEX3(4 * 8, 8, 4, " + "DMINDEX2(4, 8, ti, tj), i, j)] ~~>[TReg] reduce_sum(k, " + "fun k0 -> A(bi * 32 + (ti * 8 + i), k0) *. B(k0, bj * " + "32 + (tj * 4 + j))), by := mul_add_factor(bkIdx, 4)"); + } + } + __ghost_end(__ghost_pair_11); } + __ghost_end(__ghost_pair_12); } } - } - for (int ti = 0; ti < 4; ti++) { - for (int tj = 0; tj < 8; tj++) { - for (int i = 0; i < 8; i++) { - for (int j = 0; j < 4; j++) { - c_gmem[(32 * bi + 8 * ti + i) * n + 32 * bj + 4 * tj + j] = sum[ti * 8 * 8 * 4 + tj * 8 * 4 + 4 * i + j]; + __threadfor; + for (int ti = 0; ti < 4; ti++) { + __xconsumes( + "desync_for tj in ..8 -> for i in 0..8 -> for j in 0..4 -> " + "&sum[MINDEX3(4 * 8, 8, 4, DMINDEX2(4, 8, ti, tj), i, j)] " + "~~>[TReg] reduce_sum(exact_div(p, 4) * 4, fun k0 -> A(bi * 32 + " + "(ti * 8 + i), k0) *. B(k0, bj * 32 + (tj * 4 + j)))"); + __xproduces( + "desync_for tj in ..8 -> for _v30 in 0..8 -> for _v31 in 0..4 -> " + "&sum[MINDEX3(4 * 8, 8, 4, DMINDEX2(4, 8, ti, tj), _v30, _v31)] " + "~> UninitCellOf(TReg)"); + __xwrites( + "desync_for tj in ..8 -> for i in 0..8 -> for j in 0..4 -> " + "&c_gmem[MINDEX2(m, n, bi * 32 + (ti * 8 + i), bj * 32 + (tj * 4 " + "+ j))] ~~>[GMem] reduce_sum(p, fun k -> A(bi * 32 + (ti * 8 + " + "i), k) *. B(k, bj * 32 + (tj * 4 + j)))"); + __threadfor; + for (int tj = 0; tj < 8; tj++) { + __xconsumes( + "for i in 0..8 -> for j in 0..4 -> &sum[MINDEX3(4 * 8, 8, 4, " + "DMINDEX2(4, 8, ti, tj), i, j)] ~~>[TReg] " + "reduce_sum(exact_div(p, 4) * 4, fun k0 -> A(bi * 32 + (ti * 8 " + "+ i), k0) *. B(k0, bj * 32 + (tj * 4 + j)))"); + __xproduces( + "for _v30 in 0..8 -> for _v31 in 0..4 -> &sum[MINDEX3(4 * 8, " + "8, 4, DMINDEX2(4, 8, ti, tj), _v30, _v31)] ~> " + "UninitCellOf(TReg)"); + __xwrites( + "for i in 0..8 -> for j in 0..4 -> &c_gmem[MINDEX2(m, n, bi * " + "32 + (ti * 8 + i), bj * 32 + (tj * 4 + j))] ~~>[GMem] " + "matmul(A, B, p)(bi * 32 + (ti * 8 + i), bj * 32 + (tj * 4 + " + "j))"); + for (int i = 0; i < 8; i++) { + __xconsumes( + "for j in 0..4 -> &sum[MINDEX3(4 * 8, 8, 4, DMINDEX2(4, 8, " + "ti, tj), i, j)] ~~>[TReg] reduce_sum(exact_div(p, 4) * 4, " + "fun k0 -> A(bi * 32 + (ti * 8 + i), k0) *. B(k0, bj * 32 + " + "(tj * 4 + j)))"); + __xproduces( + "for _v21 in 0..4 -> &sum[MINDEX3(4 * 8, 8, 4, DMINDEX2(4, " + "8, ti, tj), i, _v21)] ~> UninitCellOf(TReg)"); + __xwrites( + "for j in 0..4 -> &c_gmem[MINDEX2(m, n, bi * 32 + (ti * 8 + " + "i), bj * 32 + (tj * 4 + j))] ~~>[GMem] matmul(A, B, p)(bi * " + "32 + (ti * 8 + i), bj * 32 + (tj * 4 + j))"); + for (int j = 0; j < 4; j++) { + __xconsumes( + "&sum[MINDEX3(4 * 8, 8, 4, DMINDEX2(4, 8, ti, tj), i, j)] " + "~~>[TReg] reduce_sum(exact_div(p, 4) * 4, fun k0 -> A(bi " + "* 32 + (ti * 8 + i), k0) *. B(k0, bj * 32 + (tj * 4 + " + "j)))"); + __xproduces( + "&sum[MINDEX3(4 * 8, 8, 4, DMINDEX2(4, 8, ti, tj), i, j)] " + "~> UninitCellOf(TReg)"); + __xwrites( + "&c_gmem[MINDEX2(m, n, bi * 32 + (ti * 8 + i), bj * 32 + " + "(tj * 4 + j))] ~~>[GMem] matmul(A, B, p)(bi * 32 + (ti * " + "8 + i), bj * 32 + (tj * 4 + j))"); + __ghost(assert_prop, "P := (p = exact_div(p, 4) * 4)", + "tile_div_check_k34 <- proof"); + __ghost(rewrite_linear, + "inside := fun (k: int) -> &sum[MINDEX3(4 * 8, 8, 4, " + "DMINDEX2(4, 8, ti, tj), i, j)] ~~>[TReg] " + "reduce_sum(k, fun k0 -> A(bi * 32 + (ti * 8 + i), k0) " + "*. B(k0, bj * 32 + (tj * 4 + j))), by := eq_sym(p, " + "exact_div(p, 4) * 4, tile_div_check_k34)"); + __gmem_set(&c_gmem[MINDEX2(m, n, bi * 32 + (ti * 8 + i), + bj * 32 + (tj * 4 + j))], + __treg_get(&sum[MINDEX3( + 4 * 8, 8, 4, DMINDEX2(4, 8, ti, tj), i, j)])); + } } } } + __ghost(assume, "P := (4 * 8 = MSIZE2(4, 8))"); + __ghost(dmindex2_tile, + "H := fun (f: int * int -> int) -> desync_for di1 in ..4 -> " + "desync_for di2 in ..8 -> for i1 in 0..8 -> for i2 in 0..4 -> " + "&sum[MINDEX3(4 * 8, 8, 4, f(di1, di2), i1, i2)] ~> " + "UninitCellOf(TReg), n1 := 4, n2 := 8"); + __ghost(desync_untile_divides, + "items := fun (di: int) -> for i1 in 0..8 -> for i2 in 0..4 -> " + "&sum[MINDEX3(4 * 8, 8, 4, DMINDEX1(4 * 8, di), i1, i2)] ~> " + "UninitCellOf(TReg), div_check := eq_refl(4 * 8), tile_count " + ":= 4, tile_size := 8"); + __ghost(rewrite_linear, + "from := 4 * 8, to := MSIZE2(4, 8), inside := fun (sz: int) -> " + "desync_for i in ..sz -> for i1 in 0..8 -> for i2 in 0..4 -> " + "&sum[MINDEX3(sz, 8, 4, DMINDEX1(sz, i), i1, i2)] ~> " + "UninitCellOf(TReg)"); + __ghost(rewrite_threadsctx_sz, + "from := MSIZE2(4, 8), to := MSIZE2(exact_div(32, 8), " + "exact_div(32, 4))"); } - free(sum); } - } - free(b_smem); - free(a_smem); - free(b_gmem); - free(a_gmem); - for (int i1 = 0; i1 < m; i1++) { - for (int i2 = 0; i2 < n; i2++) { - c[i1 * n + i2] = c_gmem[i1 * n + i2]; + kernel_teardown_begin(); + __with( + "grid_sz := MSIZE4(exact_div(m, 32), exact_div(n, 32), exact_div(32, " + "8), exact_div(32, 4))"); + __barrier_sequence; + { + __ghost( + kernel_teardown_sync, + "H := desync_for bi in ..exact_div(m, 32) -> desync_for bj in " + "..exact_div(n, 32) -> for _v59 in 0..8 -> for _v60 in 0..4 -> for " + "_v61 in 0..4 -> &b_smem[MINDEX4(exact_div(m, 32) * (exact_div(n, " + "32)), 8, 4, 4, DMINDEX2(exact_div(m, 32), exact_div(n, 32), bi, " + "bj), _v59, _v60, _v61)] ~> UninitCellOf(SMem)"); + __ghost( + kernel_teardown_sync, + "H := desync_for bi in ..exact_div(m, 32) -> desync_for bj in " + "..exact_div(n, 32) -> for _v52 in 0..4 -> for _v53 in 0..4 -> for " + "_v54 in 0..8 -> &a_smem[MINDEX4(exact_div(m, 32) * (exact_div(n, " + "32)), 4, 4, 8, DMINDEX2(exact_div(m, 32), exact_div(n, 32), bi, " + "bj), _v52, _v53, _v54)] ~> UninitCellOf(SMem)"); + __ghost(kernel_teardown_sync, + "H := desync_for bi in ..exact_div(m, 32) -> desync_for bj in " + "..exact_div(n, 32) -> desync_for ti in ..4 -> desync_for tj in " + "..8 -> for i in 0..8 -> for j in 0..4 -> &c_gmem[MINDEX2(m, n, " + "bi * 32 + (ti * 8 + i), bj * 32 + (tj * 4 + j))] ~~>[GMem] " + "reduce_sum(p, fun k -> A(bi * 32 + (ti * 8 + i), k) *. B(k, bj " + "* 32 + (tj * 4 + j)))"); + } + for (int bi = 0; bi < exact_div(m, 32); bi++) { + __xconsumes( + "for bj in 0..(exact_div(n, 32)) -> for ti in 0..4 -> for tj in 0..8 " + "-> for i in 0..8 -> for j in 0..4 -> &c_gmem[MINDEX2(m, n, bi * 32 " + "+ (ti * 8 + i), bj * 32 + (tj * 4 + j))] ~~>[GMem] reduce_sum(p, " + "fun k -> A(bi * 32 + (ti * 8 + i), k) *. B(k, bj * 32 + (tj * 4 + " + "j)))"); + __xproduces( + "for i in 0..32 -> for j in 0..n -> &c_gmem[MINDEX2(m, n, bi * 32 + " + "i, j)] ~~>[GMem] matmul(A, B, p)(bi * 32 + i, j)"); + __ghost(assert_prop, "P := (32 = 4 * 8)", + "tile_div_check_i17071 <- proof"); + { + for (int bj = 0; bj < exact_div(n, 32); bj++) { + __xconsumes( + "for ti in 0..4 -> for tj in 0..8 -> for i in 0..8 -> for j in " + "0..4 -> &c_gmem[MINDEX2(m, n, bi * 32 + (ti * 8 + i), bj * 32 + " + "(tj * 4 + j))] ~~>[GMem] reduce_sum(p, fun k -> A(bi * 32 + (ti " + "* 8 + i), k) *. B(k, bj * 32 + (tj * 4 + j)))"); + __xproduces( + "for ti in 0..4 -> for i in 0..8 -> for j in 0..32 -> " + "&c_gmem[MINDEX2(m, n, bi * 32 + (ti * 8 + i), bj * 32 + j)] " + "~~>[GMem] matmul(A, B, p)(bi * 32 + (ti * 8 + i), bj * 32 + j)"); + for (int ti = 0; ti < 4; ti++) { + __xconsumes( + "for tj in 0..8 -> for i in 0..8 -> for j in 0..4 -> " + "&c_gmem[MINDEX2(m, n, bi * 32 + (ti * 8 + i), bj * 32 + (tj * " + "4 + j))] ~~>[GMem] reduce_sum(p, fun k -> A(bi * 32 + (ti * 8 " + "+ i), k) *. B(k, bj * 32 + (tj * 4 + j)))"); + __xproduces( + "for i in 0..8 -> for j in 0..32 -> &c_gmem[MINDEX2(m, n, bi * " + "32 + (ti * 8 + i), bj * 32 + j)] ~~>[GMem] matmul(A, B, p)(bi " + "* 32 + (ti * 8 + i), bj * 32 + j)"); + { + __ghost(swap_groups, + "outer_range := 0..8, inner_range := 0..8, items := fun " + "(tj: int) (i: int) -> for j in 0..4 -> " + "&c_gmem[MINDEX2(m, n, bi * 32 + (ti * 8 + i), bj * 32 + " + "(tj * 4 + j))] ~~>[GMem] matmul(A, B, p)(bi * 32 + (ti " + "* 8 + i), bj * 32 + (tj * 4 + j))"); + for (int i = 0; i < 8; i++) { + __xconsumes( + "for tj in 0..8 -> for j in 0..4 -> &c_gmem[MINDEX2(m, n, " + "bi * 32 + (ti * 8 + i), bj * 32 + (tj * 4 + j))] " + "~~>[GMem] reduce_sum(p, fun k -> A(bi * 32 + (ti * 8 + " + "i), k) *. B(k, bj * 32 + (tj * 4 + j)))"); + __xproduces( + "for j in 0..32 -> &c_gmem[MINDEX2(m, n, bi * 32 + (ti * 8 " + "+ i), bj * 32 + j)] ~~>[GMem] matmul(A, B, p)(bi * 32 + " + "(ti * 8 + i), bj * 32 + j)"); + __ghost(assert_prop, "P := (32 = 8 * 4)", + "tile_div_check_j21419 <- proof"); + __ghost(untile_divides, + "div_check := tile_div_check_j21419, items := fun (j: " + "int) -> &c_gmem[MINDEX2(m, n, bi * 32 + (ti * 8 + i), " + "bj * 32 + j)] ~~>[GMem] matmul(A, B, p)(bi * 32 + (ti " + "* 8 + i), bj * 32 + j)"); + } + } + } + } + __ghost( + swap_groups, + "outer_range := 0..(exact_div(n, 32)), inner_range := 0..4, items " + ":= fun (bj: int) (ti: int) -> for i in 0..8 -> for j in 0..32 -> " + "&c_gmem[MINDEX2(m, n, bi * 32 + (ti * 8 + i), bj * 32 + j)] " + "~~>[GMem] matmul(A, B, p)(bi * 32 + (ti * 8 + i), bj * 32 + j)"); + for (int ti = 0; ti < 4; ti++) { + __xconsumes( + "for bj in 0..(exact_div(n, 32)) -> for i in 0..8 -> for j in " + "0..32 -> &c_gmem[MINDEX2(m, n, bi * 32 + (ti * 8 + i), bj * 32 " + "+ j)] ~~>[GMem] reduce_sum(p, fun k -> A(bi * 32 + (ti * 8 + " + "i), k) *. B(k, bj * 32 + j))"); + __xproduces( + "for i in 0..8 -> for j in 0..n -> &c_gmem[MINDEX2(m, n, bi * 32 " + "+ (ti * 8 + i), j)] ~~>[GMem] matmul(A, B, p)(bi * 32 + (ti * 8 " + "+ i), j)"); + __ghost( + swap_groups, + "outer_range := 0..(exact_div(n, 32)), inner_range := 0..8, " + "items := fun (bj: int) (i: int) -> for j in 0..32 -> " + "&c_gmem[MINDEX2(m, n, bi * 32 + (ti * 8 + i), bj * 32 + j)] " + "~~>[GMem] matmul(A, B, p)(bi * 32 + (ti * 8 + i), bj * 32 + j)"); + for (int i = 0; i < 8; i++) { + __xconsumes( + "for bj in 0..(exact_div(n, 32)) -> for j in 0..32 -> " + "&c_gmem[MINDEX2(m, n, bi * 32 + (ti * 8 + i), bj * 32 + j)] " + "~~>[GMem] reduce_sum(p, fun k -> A(bi * 32 + (ti * 8 + i), k) " + "*. B(k, bj * 32 + j))"); + __xproduces( + "for j in 0..n -> &c_gmem[MINDEX2(m, n, bi * 32 + (ti * 8 + " + "i), j)] ~~>[GMem] matmul(A, B, p)(bi * 32 + (ti * 8 + i), j)"); + __ghost(assert_prop, "P := (n = exact_div(n, 32) * 32)", + "tile_div_check_j712 <- proof"); + __ghost(untile_divides, + "div_check := tile_div_check_j712, items := fun (j: int) " + "-> &c_gmem[MINDEX2(m, n, bi * 32 + (ti * 8 + i), j)] " + "~~>[GMem] matmul(A, B, p)(bi * 32 + (ti * 8 + i), j)"); + } + } + __ghost(untile_divides, + "div_check := tile_div_check_i17071, items := fun (i: int) -> " + "for j in 0..n -> &c_gmem[MINDEX2(m, n, bi * 32 + i, j)] " + "~~>[GMem] matmul(A, B, p)(bi * 32 + i, j)"); + } } + __ghost(assume, + "P := (exact_div(m, 32) * (exact_div(n, 32)) = MSIZE2(exact_div(m, " + "32), exact_div(n, 32)))"); + __ghost( + dmindex2_tile, + "H := fun (f: int * int -> int) -> desync_for di1 in ..exact_div(m, " + "32) -> desync_for di2 in ..exact_div(n, 32) -> for i1 in 0..8 -> for " + "i2 in 0..4 -> for i3 in 0..4 -> &b_smem[MINDEX4(exact_div(m, 32) * " + "(exact_div(n, 32)), 8, 4, 4, f(di1, di2), i1, i2, i3)] ~> " + "UninitCellOf(SMem), n1 := exact_div(m, 32), n2 := exact_div(n, 32)"); + __ghost(desync_untile_divides, + "items := fun (di: int) -> for i1 in 0..8 -> for i2 in 0..4 -> for " + "i3 in 0..4 -> &b_smem[MINDEX4(exact_div(m, 32) * (exact_div(n, " + "32)), 8, 4, 4, DMINDEX1(exact_div(m, 32) * (exact_div(n, 32)), " + "di), i1, i2, i3)] ~> UninitCellOf(SMem), div_check := " + "eq_refl(exact_div(m, 32) * (exact_div(n, 32))), tile_count := " + "exact_div(m, 32), tile_size := exact_div(n, 32)"); + __ghost(rewrite_linear, + "from := exact_div(m, 32) * (exact_div(n, 32)), to := " + "MSIZE2(exact_div(m, 32), exact_div(n, 32)), inside := fun (sz: " + "int) -> desync_for i in ..sz -> for i1 in 0..8 -> for i2 in 0..4 " + "-> for i3 in 0..4 -> &b_smem[MINDEX4(sz, 8, 4, 4, DMINDEX1(sz, " + "i), i1, i2, i3)] ~> UninitCellOf(SMem)"); + __smem_free3(b_smem, 8, 4, 4); + __ghost(assume, + "P := (exact_div(m, 32) * (exact_div(n, 32)) = MSIZE2(exact_div(m, " + "32), exact_div(n, 32)))"); + __ghost( + dmindex2_tile, + "H := fun (f: int * int -> int) -> desync_for di1 in ..exact_div(m, " + "32) -> desync_for di2 in ..exact_div(n, 32) -> for i1 in 0..4 -> for " + "i2 in 0..4 -> for i3 in 0..8 -> &a_smem[MINDEX4(exact_div(m, 32) * " + "(exact_div(n, 32)), 4, 4, 8, f(di1, di2), i1, i2, i3)] ~> " + "UninitCellOf(SMem), n1 := exact_div(m, 32), n2 := exact_div(n, 32)"); + __ghost(desync_untile_divides, + "items := fun (di: int) -> for i1 in 0..4 -> for i2 in 0..4 -> for " + "i3 in 0..8 -> &a_smem[MINDEX4(exact_div(m, 32) * (exact_div(n, " + "32)), 4, 4, 8, DMINDEX1(exact_div(m, 32) * (exact_div(n, 32)), " + "di), i1, i2, i3)] ~> UninitCellOf(SMem), div_check := " + "eq_refl(exact_div(m, 32) * (exact_div(n, 32))), tile_count := " + "exact_div(m, 32), tile_size := exact_div(n, 32)"); + __ghost(rewrite_linear, + "from := exact_div(m, 32) * (exact_div(n, 32)), to := " + "MSIZE2(exact_div(m, 32), exact_div(n, 32)), inside := fun (sz: " + "int) -> desync_for i in ..sz -> for i1 in 0..4 -> for i2 in 0..4 " + "-> for i3 in 0..8 -> &a_smem[MINDEX4(sz, 4, 4, 8, DMINDEX1(sz, " + "i), i1, i2, i3)] ~> UninitCellOf(SMem)"); + __smem_free3(a_smem, 4, 4, 8); + __ghost(give_smem_token, "tok_sz := sizeof(float) * (8 * 4 * 4)"); + __ghost(give_smem_token, "tok_sz := sizeof(float) * (4 * 4 * 8)"); + kernel_kill(); } - free(c_gmem); + __ghost( + untile_divides, + "div_check := tile_div_check_i, items := fun (i: int) -> for j in 0..n " + "-> &c_gmem[MINDEX2(m, n, i, j)] ~~>[GMem] matmul(A, B, p)(i, j)"); + __ghost([&]() { + __preserves("b_gmem ~> UninitMatrix2Of(p, n, GMem)"); + __admitted(); + __with("justif := shift_groups"); + }); + gmem_free(b_gmem); + __ghost([&]() { + __preserves("a_gmem ~> UninitMatrix2Of(m, p, GMem)"); + __admitted(); + __with("justif := shift_groups"); + }); + gmem_free(a_gmem); + memcpy_device_to_host2(c, c_gmem, m, n); + __ghost([&]() { + __preserves("c_gmem ~> UninitMatrix2Of(m, n, GMem)"); + __admitted(); + __with("justif := shift_groups"); + }); + gmem_free(c_gmem); } diff --git a/case_studies/gpu/reduction/reduce.ml b/case_studies/gpu/reduction/reduce.ml index 73b4b6a4e..41f02e821 100644 --- a/case_studies/gpu/reduction/reduce.ml +++ b/case_studies/gpu/reduction/reduce.ml @@ -5,9 +5,9 @@ let _ = Flags.check_validity := true let _ = Flags.use_resources_with_models := true let _ = Flags.preserve_specs_only := true let _ = Flags.pretty_matrix_notation := false -let _ = Flags.recompute_resources_between_steps := true +let _ = Flags.recompute_resources_between_steps := false let _ = Flags.disable_stringreprs := true -let _ = Flags.save_ast_for_steps := None (* Some Flags.Steps_important *) +let _ = Flags.save_ast_for_steps := Some Flags.Steps_script (* Some Flags.Steps_important *) let _ = Flags.only_big_steps := true let _ = Run.script_cpp (fun () -> ()) @@ -183,7 +183,6 @@ let _ = Run.script_cpp_stage stage_ok (fun () -> But it's also not declared on the host level. Normally, having a variable as thread for loop bounds is illegal, but this is just a pure constant, so it can be inlined as a quick fix to the problem. *) !! Variable.inline [cVarDef ~regexp:true "N.+"]; - !! Flags.recompute_resources_between_steps := false; !! Trace.without_substep_validity_checks (fun () -> Instr.move ~dest:[tFirst; cMark "kernel_sequence"] [cCall "kernel_launch"]; Trace.generate_cuda ~check_expected:true (); diff --git a/case_studies/gpu/reduction/reduce_exp.cpp b/case_studies/gpu/reduction/reduce_exp.cpp index bc8349a94..a3409f2dd 100644 --- a/case_studies/gpu/reduction/reduce_exp.cpp +++ b/case_studies/gpu/reduction/reduce_exp.cpp @@ -588,7 +588,7 @@ float reduce(float* arr, int N) { __ghost( rewrite_linear, "from := exact_div(N, 512), to := MSIZE1(exact_div(N, 512)), inside := " - "fun (sz: int) -> for i in 0..sz -> for i1 in 0..256 -> " + "fun (sz: int) -> desync_for i in ..sz -> for i1 in 0..256 -> " "&tile[MINDEX2(sz, 256, DMINDEX1(sz, i), i1)] ~> UninitCellOf(SMem)"); __smem_free1(tile, 256); __ghost(give_smem_token, "tok_sz := sizeof(float) * 256"); diff --git a/case_studies/gpu/transpose/transpose.ml b/case_studies/gpu/transpose/transpose.ml index 17b5f1838..ee44c8eef 100644 --- a/case_studies/gpu/transpose/transpose.ml +++ b/case_studies/gpu/transpose/transpose.ml @@ -2,12 +2,12 @@ open Optitrust open Prelude let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +let _ = Flags.recompute_resources_between_steps := false let _ = Flags.disable_stringreprs := true let _ = Flags.save_ast_for_steps := Some Flags.Steps_important let _ = Flags.pretty_matrix_notation := false -let stage_ok = fun i -> i = 5 +let stage_ok = fun i -> true (* i = 5 *) let _ = Run.script_cpp_stage (stage_ok) (fun () -> (* Hoist global memories *) diff --git a/case_studies/gpu/transpose/transpose_exp.cpp b/case_studies/gpu/transpose/transpose_exp.cpp index 094379ef9..a68837d60 100644 --- a/case_studies/gpu/transpose/transpose_exp.cpp +++ b/case_studies/gpu/transpose/transpose_exp.cpp @@ -1,14 +1,7 @@ -#include "optitrust_models.h" - #include "optitrust_gpu.h" +#include "optitrust_models.h" - - - - - - - void transpose (float* a, float* b, int W, int H) { +void transpose(float* a, float* b, int W, int H) { __requires("A: int * int -> float"); __requires("(exact_div(W, 32) >= 0)"); __preserves("HostCtx"); @@ -16,7 +9,7 @@ __reads("a ~> Matrix2(H, W, A)"); float* const d_a = __gmem_malloc2(H, W); __with("T := float"); - __ghost([&] () { + __ghost([&]() { __preserves("d_a ~> UninitMatrix2Of(H, W, GMem)"); __admitted(); __with("justif := shift_groups"); @@ -24,115 +17,299 @@ memcpy_host_to_device2(d_a, a, H, W); float* const d_b = __gmem_malloc2(W, H); __with("T := float"); - __ghost([&] () { + __ghost([&]() { __preserves("d_b ~> UninitMatrix2Of(W, H, GMem)"); __admitted(); __with("justif := shift_groups"); }); - __ghost(assert_prop, "P := (W = exact_div(W, 32) * 32)", "tile_div_check_x <- proof"); - __ghost(tile_divides, "div_check := tile_div_check_x, items := fun (x: int) -> for y in 0..H -> &d_b[MINDEX2(W, H, x, y)] ~> UninitCellOf(GMem)"); - /*@kernel_sequence*/{ - kernel_launch(MSIZE2(exact_div(H, 32), exact_div(W, 32)), MSIZE2(16, 32), sizeof(float) * ( - 32 * 32) + 0); - __ghost(assume, "P := (exact_div(H, 32) * (exact_div(W, 32)) = MSIZE2(exact_div(H, 32), exact_div(W, 32)))"); - __ghost(assume, "P := (MSIZE2(exact_div(H, 32), exact_div(W, 32)) * MSIZE2(16, 32) = MSIZE4(exact_div(H, 32), exact_div(W, 32), 16, 32))"); - __ghost(assume, "P := (MSIZE2(exact_div(H, 32), exact_div(W, 32)) = exact_div(H, 32) * (exact_div(W, 32)))"); + __ghost(assert_prop, "P := (W = exact_div(W, 32) * 32)", + "tile_div_check_x <- proof"); + __ghost(tile_divides, + "div_check := tile_div_check_x, items := fun (x: int) -> for y in " + "0..H -> &d_b[MINDEX2(W, H, x, y)] ~> UninitCellOf(GMem)"); + /*@kernel_sequence*/ { + kernel_launch(MSIZE2(exact_div(H, 32), exact_div(W, 32)), MSIZE2(16, 32), + sizeof(float) * (32 * 32) + 0); + __ghost(assume, + "P := (exact_div(H, 32) * (exact_div(W, 32)) = MSIZE2(exact_div(H, " + "32), exact_div(W, 32)))"); + __ghost(assume, + "P := (MSIZE2(exact_div(H, 32), exact_div(W, 32)) * MSIZE2(16, 32) " + "= MSIZE4(exact_div(H, 32), exact_div(W, 32), 16, 32))"); + __ghost(assume, + "P := (MSIZE2(exact_div(H, 32), exact_div(W, 32)) = exact_div(H, " + "32) * (exact_div(W, 32)))"); __ghost(take_smem_token, "tok_sz := sizeof(float) * (32 * 32)"); - for (int bx = 0; bx < exact_div(W, 32); bx++) { + for (int bx = 0; bx < exact_div(W, 32); bx++) { __strict(); - __xconsumes("for x in 0..32 -> for y in 0..H -> &d_b[MINDEX2(W, H, bx * 32 + x, y)] ~> UninitCellOf(GMem)"); - __xproduces("for j in 0..(exact_div(H, 32)) -> for i in 0..32 -> for y in 0..32 -> &d_b[MINDEX2(W, H, bx * 32 + i, j * 32 + y)] ~> UninitCellOf(GMem)"); - for (int x = 0; x < 32; x++) { + __xconsumes( + "for x in 0..32 -> for y in 0..H -> &d_b[MINDEX2(W, H, bx * 32 + x, " + "y)] ~> UninitCellOf(GMem)"); + __xproduces( + "for j in 0..(exact_div(H, 32)) -> for i in 0..32 -> for y in 0..32 " + "-> &d_b[MINDEX2(W, H, bx * 32 + i, j * 32 + y)] ~> " + "UninitCellOf(GMem)"); + for (int x = 0; x < 32; x++) { __strict(); - __xconsumes("for y in 0..H -> &d_b[MINDEX2(W, H, bx * 32 + x, y)] ~> UninitCellOf(GMem)"); - __xproduces("for bi in 0..(exact_div(H, 32)) -> for i in 0..32 -> &d_b[MINDEX2(W, H, bx * 32 + x, bi * 32 + i)] ~> UninitCellOf(GMem)"); - __ghost(assert_prop, "P := (H = exact_div(H, 32) * 32)", "tile_div_check_y <- proof"); - __ghost(tile_divides, "div_check := tile_div_check_y, items := fun (y: int) -> &d_b[MINDEX2(W, H, bx * 32 + x, y)] ~> UninitCellOf(GMem)"); + __xconsumes( + "for y in 0..H -> &d_b[MINDEX2(W, H, bx * 32 + x, y)] ~> " + "UninitCellOf(GMem)"); + __xproduces( + "for bi in 0..(exact_div(H, 32)) -> for i in 0..32 -> " + "&d_b[MINDEX2(W, H, bx * 32 + x, bi * 32 + i)] ~> " + "UninitCellOf(GMem)"); + __ghost(assert_prop, "P := (H = exact_div(H, 32) * 32)", + "tile_div_check_y <- proof"); + __ghost(tile_divides, + "div_check := tile_div_check_y, items := fun (y: int) -> " + "&d_b[MINDEX2(W, H, bx * 32 + x, y)] ~> UninitCellOf(GMem)"); } - __ghost(swap_groups, "outer_range := 0..32, inner_range := 0..(exact_div(H, 32)), items := fun (x: int) (by: int) -> for y in 0..32 -> &d_b[MINDEX2(W, H, bx * 32 + x, by * 32 + y)] ~> UninitCellOf(GMem)"); + __ghost( + swap_groups, + "outer_range := 0..32, inner_range := 0..(exact_div(H, 32)), items " + ":= fun (x: int) (by: int) -> for y in 0..32 -> &d_b[MINDEX2(W, H, " + "bx * 32 + x, by * 32 + y)] ~> UninitCellOf(GMem)"); } - __ghost(swap_groups, "outer_range := 0..(exact_div(W, 32)), inner_range := 0..(exact_div(H, 32)), items := fun (bx: int) (by: int) -> for x in 0..32 -> for y in 0..32 -> &d_b[MINDEX2(W, H, bx * 32 + x, by * 32 + y)] ~> UninitCellOf(GMem)"); + __ghost(swap_groups, + "outer_range := 0..(exact_div(W, 32)), inner_range := " + "0..(exact_div(H, 32)), items := fun (bx: int) (by: int) -> for x " + "in 0..32 -> for y in 0..32 -> &d_b[MINDEX2(W, H, bx * 32 + x, by " + "* 32 + y)] ~> UninitCellOf(GMem)"); float* const tile = __smem_malloc2(32, 32); __with("T := float"); - __ghost(rewrite_linear, "from := MSIZE2(exact_div(H, 32), exact_div(W, 32)), to := exact_div(H, 32) * (exact_div(W, 32)), inside := fun (sz: int) -> desync_for i in ..sz -> for i1 in 0..32 -> for i2 in 0..32 -> &tile[MINDEX3(sz, 32, 32, DMINDEX1(sz, i), i1, i2)] ~> UninitCellOf(SMem)"); - __ghost(desync_tile_divides, "items := fun (di: int) -> for i1 in 0..32 -> for i2 in 0..32 -> &tile[MINDEX3(exact_div(H, 32) * (exact_div(W, 32)), 32, 32, DMINDEX1(exact_div(H, 32) * (exact_div(W, 32)), di), i1, i2)] ~> UninitCellOf(SMem), div_check := eq_refl(exact_div(H, 32) * (exact_div(W, 32))), tile_count := exact_div(H, 32), tile_size := exact_div(W, 32)"); - __ghost(dmindex2_untile, "H := fun (f: int * int -> int) -> desync_for di1 in ..exact_div(H, 32) -> desync_for di2 in ..exact_div(W, 32) -> for i1 in 0..32 -> for i2 in 0..32 -> &tile[MINDEX3(exact_div(H, 32) * (exact_div(W, 32)), 32, 32, f(di1, di2), i1, i2)] ~> UninitCellOf(SMem), n1 := exact_div(H, 32), n2 := exact_div(W, 32)"); + __ghost(rewrite_linear, + "from := MSIZE2(exact_div(H, 32), exact_div(W, 32)), to := " + "exact_div(H, 32) * (exact_div(W, 32)), inside := fun (sz: int) -> " + "desync_for i in ..sz -> for i1 in 0..32 -> for i2 in 0..32 -> " + "&tile[MINDEX3(sz, 32, 32, DMINDEX1(sz, i), i1, i2)] ~> " + "UninitCellOf(SMem)"); + __ghost(desync_tile_divides, + "items := fun (di: int) -> for i1 in 0..32 -> for i2 in 0..32 -> " + "&tile[MINDEX3(exact_div(H, 32) * (exact_div(W, 32)), 32, 32, " + "DMINDEX1(exact_div(H, 32) * (exact_div(W, 32)), di), i1, i2)] ~> " + "UninitCellOf(SMem), div_check := eq_refl(exact_div(H, 32) * " + "(exact_div(W, 32))), tile_count := exact_div(H, 32), tile_size := " + "exact_div(W, 32)"); + __ghost( + dmindex2_untile, + "H := fun (f: int * int -> int) -> desync_for di1 in ..exact_div(H, " + "32) -> desync_for di2 in ..exact_div(W, 32) -> for i1 in 0..32 -> for " + "i2 in 0..32 -> &tile[MINDEX3(exact_div(H, 32) * (exact_div(W, 32)), " + "32, 32, f(di1, di2), i1, i2)] ~> UninitCellOf(SMem), n1 := " + "exact_div(H, 32), n2 := exact_div(W, 32)"); kernel_setup_end(); __with("grid_sz := MSIZE4(exact_div(H, 32), exact_div(W, 32), 16, 32)"); - __threadfor; for (int by = 0; by < exact_div(H, 32); by++) { + __threadfor; + for (int by = 0; by < exact_div(H, 32); by++) { __strict(); - __sreads("KernelParams(MSIZE2(exact_div(H, 32), exact_div(W, 32)), MSIZE2(16, 32), sizeof(float) * (32 * 32) + 0)"); + __sreads( + "KernelParams(MSIZE2(exact_div(H, 32), exact_div(W, 32)), MSIZE2(16, " + "32), sizeof(float) * (32 * 32) + 0)"); __sreads("d_a ~> Matrix2Of(H, W, GMem, A)"); - __xconsumes("for bx in 0..(exact_div(W, 32)) -> for x in 0..32 -> for y in 0..32 -> &d_b[MINDEX2(W, H, bx * 32 + x, by * 32 + y)] ~> UninitCellOf(GMem)"); - __xproduces("desync_for bx in ..exact_div(W, 32) -> for j in 0..2 -> desync_for x in ..16 -> desync_for y in ..32 -> &d_b[MINDEX2(W, H, bx * 32 + (j * 16 + x), by * 32 + y)] ~~>[GMem] A(by * 32 + y, bx * 32 + (j * 16 + x))"); - __xwrites("desync_for bx in ..exact_div(W, 32) -> for y in 0..32 -> for x in 0..32 -> &tile[MINDEX3(exact_div(H, 32) * (exact_div(W, 32)), 32, 32, DMINDEX2(exact_div(H, 32), exact_div(W, 32), by, bx), y, x)] ~~>[SMem] A(by * 32 + y, bx * 32 + x)"); - __threadfor; for (int bx = 0; bx < exact_div(W, 32); bx++) { + __xconsumes( + "for bx in 0..(exact_div(W, 32)) -> for x in 0..32 -> for y in 0..32 " + "-> &d_b[MINDEX2(W, H, bx * 32 + x, by * 32 + y)] ~> " + "UninitCellOf(GMem)"); + __xproduces( + "desync_for bx in ..exact_div(W, 32) -> for j in 0..2 -> desync_for " + "x in ..16 -> desync_for y in ..32 -> &d_b[MINDEX2(W, H, bx * 32 + " + "(j * 16 + x), by * 32 + y)] ~~>[GMem] A(by * 32 + y, bx * 32 + (j * " + "16 + x))"); + __xwrites( + "desync_for bx in ..exact_div(W, 32) -> for y in 0..32 -> for x in " + "0..32 -> &tile[MINDEX3(exact_div(H, 32) * (exact_div(W, 32)), 32, " + "32, DMINDEX2(exact_div(H, 32), exact_div(W, 32), by, bx), y, x)] " + "~~>[SMem] A(by * 32 + y, bx * 32 + x)"); + __threadfor; + for (int bx = 0; bx < exact_div(W, 32); bx++) { __strict(); - __sreads("KernelParams(MSIZE2(exact_div(H, 32), exact_div(W, 32)), MSIZE2(16, 32), sizeof(float) * (32 * 32) + 0)"); + __sreads( + "KernelParams(MSIZE2(exact_div(H, 32), exact_div(W, 32)), " + "MSIZE2(16, 32), sizeof(float) * (32 * 32) + 0)"); __sreads("d_a ~> Matrix2Of(H, W, GMem, A)"); - __xconsumes("for x in 0..32 -> for y in 0..32 -> &d_b[MINDEX2(W, H, bx * 32 + x, by * 32 + y)] ~> UninitCellOf(GMem)"); - __xproduces("for j in 0..2 -> desync_for x in ..16 -> desync_for y in ..32 -> &d_b[MINDEX2(W, H, bx * 32 + (j * 16 + x), by * 32 + y)] ~~>[GMem] A(by * 32 + y, bx * 32 + (j * 16 + x))"); - __xwrites("for y in 0..32 -> for x in 0..32 -> &tile[MINDEX3(exact_div(H, 32) * (exact_div(W, 32)), 32, 32, DMINDEX2(exact_div(H, 32), exact_div(W, 32), by, bx), y, x)] ~~>[SMem] A(by * 32 + y, bx * 32 + x)"); - __ghost(swap_groups, "outer_range := 0..32, inner_range := 0..32, items := fun (x: int) (y: int) -> &d_b[MINDEX2(W, H, bx * 32 + x, by * 32 + y)] ~> UninitCellOf(GMem)"); + __xconsumes( + "for x in 0..32 -> for y in 0..32 -> &d_b[MINDEX2(W, H, bx * 32 + " + "x, by * 32 + y)] ~> UninitCellOf(GMem)"); + __xproduces( + "for j in 0..2 -> desync_for x in ..16 -> desync_for y in ..32 -> " + "&d_b[MINDEX2(W, H, bx * 32 + (j * 16 + x), by * 32 + y)] " + "~~>[GMem] A(by * 32 + y, bx * 32 + (j * 16 + x))"); + __xwrites( + "for y in 0..32 -> for x in 0..32 -> &tile[MINDEX3(exact_div(H, " + "32) * (exact_div(W, 32)), 32, 32, DMINDEX2(exact_div(H, 32), " + "exact_div(W, 32), by, bx), y, x)] ~~>[SMem] A(by * 32 + y, bx * " + "32 + x)"); + __ghost(swap_groups, + "outer_range := 0..32, inner_range := 0..32, items := fun (x: " + "int) (y: int) -> &d_b[MINDEX2(W, H, bx * 32 + x, by * 32 + " + "y)] ~> UninitCellOf(GMem)"); __ghost(assert_prop, "P := (32 = 2 * 16)", "tile_div_check_y <- proof"); - __ghost(tile_divides, "div_check := tile_div_check_y, items := fun (y: int) -> for x in 0..32 -> &tile[MINDEX3(exact_div(H, 32) * (exact_div(W, 32)), 32, 32, DMINDEX2(exact_div(H, 32), exact_div(W, 32), by, bx), y, x)] ~> UninitCellOf(SMem)"); - for (int j = 0; j < 2; j++) { + __ghost(tile_divides, + "div_check := tile_div_check_y, items := fun (y: int) -> for x " + "in 0..32 -> &tile[MINDEX3(exact_div(H, 32) * (exact_div(W, " + "32)), 32, 32, DMINDEX2(exact_div(H, 32), exact_div(W, 32), " + "by, bx), y, x)] ~> UninitCellOf(SMem)"); + for (int j = 0; j < 2; j++) { __strict(); - __spreserves("ThreadsCtx(MINDEX3(exact_div(H, 32), exact_div(W, 32), 0, by, bx, 0)..+MSIZE2(16, 32))"); + __spreserves( + "ThreadsCtx(MINDEX3(exact_div(H, 32), exact_div(W, 32), 0, by, " + "bx, 0)..+MSIZE2(16, 32))"); __sreads("d_a ~> Matrix2Of(H, W, GMem, A)"); - __xconsumes("for y in 0..16 -> for x in 0..32 -> &tile[MINDEX3(exact_div(H, 32) * (exact_div(W, 32)), 32, 32, DMINDEX2(exact_div(H, 32), exact_div(W, 32), by, bx), j * 16 + y, x)] ~> UninitCellOf(SMem)"); - __xproduces("desync_for y in ..16 -> desync_for x in ..32 -> &tile[MINDEX3(exact_div(H, 32) * (exact_div(W, 32)), 32, 32, DMINDEX2(exact_div(H, 32), exact_div(W, 32), by, bx), j * 16 + y, x)] ~~>[SMem] A(by * 32 + (j * 16 + y), bx * 32 + x)"); - __threadfor; for (int y = 0; y < 16; y++) { + __xconsumes( + "for y in 0..16 -> for x in 0..32 -> &tile[MINDEX3(exact_div(H, " + "32) * (exact_div(W, 32)), 32, 32, DMINDEX2(exact_div(H, 32), " + "exact_div(W, 32), by, bx), j * 16 + y, x)] ~> " + "UninitCellOf(SMem)"); + __xproduces( + "desync_for y in ..16 -> desync_for x in ..32 -> " + "&tile[MINDEX3(exact_div(H, 32) * (exact_div(W, 32)), 32, 32, " + "DMINDEX2(exact_div(H, 32), exact_div(W, 32), by, bx), j * 16 + " + "y, x)] ~~>[SMem] A(by * 32 + (j * 16 + y), bx * 32 + x)"); + __threadfor; + for (int y = 0; y < 16; y++) { __strict(); __sreads("d_a ~> Matrix2Of(H, W, GMem, A)"); - __xconsumes("for x in 0..32 -> &tile[MINDEX3(exact_div(H, 32) * (exact_div(W, 32)), 32, 32, DMINDEX2(exact_div(H, 32), exact_div(W, 32), by, bx), j * 16 + y, x)] ~> UninitCellOf(SMem)"); - __xproduces("desync_for x in ..32 -> &tile[MINDEX3(exact_div(H, 32) * (exact_div(W, 32)), 32, 32, DMINDEX2(exact_div(H, 32), exact_div(W, 32), by, bx), j * 16 + y, x)] ~~>[SMem] A(by * 32 + (j * 16 + y), bx * 32 + x)"); - __ghost(tiled_index_in_range, "tile_index := j, index := y, div_check := tile_div_check_y"); - __threadfor; for (int x = 0; x < 32; x++) { + __xconsumes( + "for x in 0..32 -> &tile[MINDEX3(exact_div(H, 32) * " + "(exact_div(W, 32)), 32, 32, DMINDEX2(exact_div(H, 32), " + "exact_div(W, 32), by, bx), j * 16 + y, x)] ~> " + "UninitCellOf(SMem)"); + __xproduces( + "desync_for x in ..32 -> &tile[MINDEX3(exact_div(H, 32) * " + "(exact_div(W, 32)), 32, 32, DMINDEX2(exact_div(H, 32), " + "exact_div(W, 32), by, bx), j * 16 + y, x)] ~~>[SMem] A(by * " + "32 + (j * 16 + y), bx * 32 + x)"); + __ghost( + tiled_index_in_range, + "tile_index := j, index := y, div_check := tile_div_check_y"); + __threadfor; + for (int x = 0; x < 32; x++) { __strict(); __sreads("d_a ~> Matrix2Of(H, W, GMem, A)"); - __xwrites("&tile[MINDEX3(exact_div(H, 32) * (exact_div(W, 32)), 32, 32, DMINDEX2(exact_div(H, 32), exact_div(W, 32), by, bx), j * 16 + y, x)] ~~>[SMem] A(by * 32 + (j * 16 + y), bx * 32 + x)"); - __ghost(assert_prop, "P := (H = exact_div(H, 32) * 32)", "tile_div_check_y13 <- proof"); - __ghost(tiled_index_in_range, "tile_index := by, index := j * 16 + y, div_check := tile_div_check_y13"); - __ghost(tiled_index_in_range, "tile_index := bx, index := x, div_check := tile_div_check_x"); - const __ghost_fn __ghost_pair_2 = __ghost_begin(ro_matrix2_focus, "matrix := d_a, i := by * 32 + (j * 16 + y), j := bx * 32 + x"); - __smem_set(&tile[MINDEX3(exact_div(H, 32) * (exact_div(W, 32)), 32, 32, DMINDEX2(exact_div(H, 32), exact_div(W, 32), by, bx), j * 16 + y, x)], __gmem_get(&d_a[MINDEX2(H, W, by * 32 + ( - j * 16 + y), bx * 32 + x)])); + __xwrites( + "&tile[MINDEX3(exact_div(H, 32) * (exact_div(W, 32)), 32, " + "32, DMINDEX2(exact_div(H, 32), exact_div(W, 32), by, bx), j " + "* 16 + y, x)] ~~>[SMem] A(by * 32 + (j * 16 + y), bx * 32 + " + "x)"); + __ghost(assert_prop, "P := (H = exact_div(H, 32) * 32)", + "tile_div_check_y13 <- proof"); + __ghost(tiled_index_in_range, + "tile_index := by, index := j * 16 + y, div_check := " + "tile_div_check_y13"); + __ghost(tiled_index_in_range, + "tile_index := bx, index := x, div_check := " + "tile_div_check_x"); + const __ghost_fn __ghost_pair_2 = + __ghost_begin(ro_matrix2_focus, + "matrix := d_a, i := by * 32 + (j * 16 + y), j " + ":= bx * 32 + x"); + __smem_set( + &tile[MINDEX3( + exact_div(H, 32) * (exact_div(W, 32)), 32, 32, + DMINDEX2(exact_div(H, 32), exact_div(W, 32), by, bx), + j * 16 + y, x)], + __gmem_get(&d_a[MINDEX2(H, W, by * 32 + (j * 16 + y), + bx * 32 + x)])); __ghost_end(__ghost_pair_2); } } } - __barrier_sequence; { + __barrier_sequence; + { blocksync(); - __with("H := for j in 0..2 -> desync_for y in ..16 -> desync_for x in ..32 -> &tile[MINDEX3(exact_div(H, 32) * (exact_div(W, 32)), 32, 32, DMINDEX2(exact_div(H, 32), exact_div(W, 32), by, bx), j * 16 + y, x)] ~~>[SMem] A(by * 32 + (j * 16 + y), bx * 32 + x)"); + __with( + "H := for j in 0..2 -> desync_for y in ..16 -> desync_for x in " + "..32 -> &tile[MINDEX3(exact_div(H, 32) * (exact_div(W, 32)), " + "32, 32, DMINDEX2(exact_div(H, 32), exact_div(W, 32), by, bx), j " + "* 16 + y, x)] ~~>[SMem] A(by * 32 + (j * 16 + y), bx * 32 + x)"); } - __ghost(untile_divides, "div_check := tile_div_check_y, items := fun (y: int) -> for x in 0..32 -> &tile[MINDEX3(exact_div(H, 32) * (exact_div(W, 32)), 32, 32, DMINDEX2(exact_div(H, 32), exact_div(W, 32), by, bx), y, x)] ~~>[SMem] A(by * 32 + y, bx * 32 + x)"); - __ghost(swap_groups, "outer_range := 0..32, inner_range := 0..32, items := fun (y: int) (x: int) -> &d_b[MINDEX2(W, H, bx * 32 + x, by * 32 + y)] ~> UninitCellOf(GMem)"); - __ghost(assert_prop, "P := (32 = 2 * 16)", "tile_div_check_x11 <- proof"); - __ghost(tile_divides, "div_check := tile_div_check_x11, items := fun (x: int) -> for y in 0..32 -> &d_b[MINDEX2(W, H, bx * 32 + x, by * 32 + y)] ~> UninitCellOf(GMem)"); - for (int j = 0; j < 2; j++) { + __ghost(untile_divides, + "div_check := tile_div_check_y, items := fun (y: int) -> for x " + "in 0..32 -> &tile[MINDEX3(exact_div(H, 32) * (exact_div(W, " + "32)), 32, 32, DMINDEX2(exact_div(H, 32), exact_div(W, 32), " + "by, bx), y, x)] ~~>[SMem] A(by * 32 + y, bx * 32 + x)"); + __ghost(swap_groups, + "outer_range := 0..32, inner_range := 0..32, items := fun (y: " + "int) (x: int) -> &d_b[MINDEX2(W, H, bx * 32 + x, by * 32 + " + "y)] ~> UninitCellOf(GMem)"); + __ghost(assert_prop, "P := (32 = 2 * 16)", + "tile_div_check_x11 <- proof"); + __ghost(tile_divides, + "div_check := tile_div_check_x11, items := fun (x: int) -> for " + "y in 0..32 -> &d_b[MINDEX2(W, H, bx * 32 + x, by * 32 + y)] " + "~> UninitCellOf(GMem)"); + for (int j = 0; j < 2; j++) { __strict(); - __spreserves("ThreadsCtx(MINDEX3(exact_div(H, 32), exact_div(W, 32), 0, by, bx, 0)..+MSIZE2(16, 32))"); - __sreads("for y in 0..32 -> for x in 0..32 -> &tile[MINDEX3(exact_div(H, 32) * (exact_div(W, 32)), 32, 32, DMINDEX2(exact_div(H, 32), exact_div(W, 32), by, bx), y, x)] ~~>[SMem] A(by * 32 + y, bx * 32 + x)"); - __xconsumes("for x in 0..16 -> for y in 0..32 -> &d_b[MINDEX2(W, H, bx * 32 + (j * 16 + x), by * 32 + y)] ~> UninitCellOf(GMem)"); - __xproduces("desync_for x in ..16 -> desync_for y in ..32 -> &d_b[MINDEX2(W, H, bx * 32 + (j * 16 + x), by * 32 + y)] ~~>[GMem] A(by * 32 + y, bx * 32 + (j * 16 + x))"); - __threadfor; for (int x = 0; x < 16; x++) { + __spreserves( + "ThreadsCtx(MINDEX3(exact_div(H, 32), exact_div(W, 32), 0, by, " + "bx, 0)..+MSIZE2(16, 32))"); + __sreads( + "for y in 0..32 -> for x in 0..32 -> &tile[MINDEX3(exact_div(H, " + "32) * (exact_div(W, 32)), 32, 32, DMINDEX2(exact_div(H, 32), " + "exact_div(W, 32), by, bx), y, x)] ~~>[SMem] A(by * 32 + y, bx * " + "32 + x)"); + __xconsumes( + "for x in 0..16 -> for y in 0..32 -> &d_b[MINDEX2(W, H, bx * 32 " + "+ (j * 16 + x), by * 32 + y)] ~> UninitCellOf(GMem)"); + __xproduces( + "desync_for x in ..16 -> desync_for y in ..32 -> &d_b[MINDEX2(W, " + "H, bx * 32 + (j * 16 + x), by * 32 + y)] ~~>[GMem] A(by * 32 + " + "y, bx * 32 + (j * 16 + x))"); + __threadfor; + for (int x = 0; x < 16; x++) { __strict(); - __sreads("for y in 0..32 -> for x in 0..32 -> &tile[MINDEX3(exact_div(H, 32) * (exact_div(W, 32)), 32, 32, DMINDEX2(exact_div(H, 32), exact_div(W, 32), by, bx), y, x)] ~~>[SMem] A(by * 32 + y, bx * 32 + x)"); - __xconsumes("for y in 0..32 -> &d_b[MINDEX2(W, H, bx * 32 + (j * 16 + x), by * 32 + y)] ~> UninitCellOf(GMem)"); - __xproduces("desync_for y in ..32 -> &d_b[MINDEX2(W, H, bx * 32 + (j * 16 + x), by * 32 + y)] ~~>[GMem] A(by * 32 + y, bx * 32 + (j * 16 + x))"); - __ghost(tiled_index_in_range, "tile_index := j, index := x, div_check := tile_div_check_x11"); - __threadfor; for (int y = 0; y < 32; y++) { + __sreads( + "for y in 0..32 -> for x in 0..32 -> " + "&tile[MINDEX3(exact_div(H, 32) * (exact_div(W, 32)), 32, 32, " + "DMINDEX2(exact_div(H, 32), exact_div(W, 32), by, bx), y, x)] " + "~~>[SMem] A(by * 32 + y, bx * 32 + x)"); + __xconsumes( + "for y in 0..32 -> &d_b[MINDEX2(W, H, bx * 32 + (j * 16 + x), " + "by * 32 + y)] ~> UninitCellOf(GMem)"); + __xproduces( + "desync_for y in ..32 -> &d_b[MINDEX2(W, H, bx * 32 + (j * 16 " + "+ x), by * 32 + y)] ~~>[GMem] A(by * 32 + y, bx * 32 + (j * " + "16 + x))"); + __ghost( + tiled_index_in_range, + "tile_index := j, index := x, div_check := tile_div_check_x11"); + __threadfor; + for (int y = 0; y < 32; y++) { __strict(); - __sreads("for y in 0..32 -> for x in 0..32 -> &tile[MINDEX3(exact_div(H, 32) * (exact_div(W, 32)), 32, 32, DMINDEX2(exact_div(H, 32), exact_div(W, 32), by, bx), y, x)] ~~>[SMem] A(by * 32 + y, bx * 32 + x)"); - __xwrites("&d_b[MINDEX2(W, H, bx * 32 + (j * 16 + x), by * 32 + y)] ~~>[GMem] A(by * 32 + y, bx * 32 + (j * 16 + x))"); - const __ghost_fn __ghost_pair_5 = __ghost_begin(ro_group_focus, "i := y, items := fun (y: int) -> for x in 0..32 -> &tile[MINDEX3(exact_div(H, 32) * (exact_div(W, 32)), 32, 32, DMINDEX2(exact_div(H, 32), exact_div(W, 32), by, bx), y, x)] ~~>[SMem] A(by * 32 + y, bx * 32 + x)"); - const __ghost_fn __ghost_pair_4 = __ghost_begin(ro_group_focus, "i := j * 16 + x, items := fun (x: int) -> &tile[MINDEX3(exact_div(H, 32) * (exact_div(W, 32)), 32, 32, DMINDEX2(exact_div(H, 32), exact_div(W, 32), by, bx), y, x)] ~~>[SMem] A(by * 32 + y, bx * 32 + x)"); - __ghost(assert_prop, "P := (H = exact_div(H, 32) * 32)", "tile_div_check_y135 <- proof"); - __ghost(tiled_index_in_range, "tile_index := by, index := y, div_check := tile_div_check_y135"); - __ghost(tiled_index_in_range, "tile_index := bx, index := j * 16 + x, div_check := tile_div_check_x"); - __gmem_set(&d_b[MINDEX2(W, H, bx * 32 + (j * 16 + x), by * 32 + y)], __smem_get(&tile[MINDEX3(exact_div(H, 32) * ( - exact_div(W, 32)), 32, 32, DMINDEX2(exact_div(H, 32), exact_div(W, 32), by, bx), y, j * 16 + x)])); + __sreads( + "for y in 0..32 -> for x in 0..32 -> " + "&tile[MINDEX3(exact_div(H, 32) * (exact_div(W, 32)), 32, " + "32, DMINDEX2(exact_div(H, 32), exact_div(W, 32), by, bx), " + "y, x)] ~~>[SMem] A(by * 32 + y, bx * 32 + x)"); + __xwrites( + "&d_b[MINDEX2(W, H, bx * 32 + (j * 16 + x), by * 32 + y)] " + "~~>[GMem] A(by * 32 + y, bx * 32 + (j * 16 + x))"); + const __ghost_fn __ghost_pair_5 = __ghost_begin( + ro_group_focus, + "i := y, items := fun (y: int) -> for x in 0..32 -> " + "&tile[MINDEX3(exact_div(H, 32) * (exact_div(W, 32)), 32, " + "32, DMINDEX2(exact_div(H, 32), exact_div(W, 32), by, bx), " + "y, x)] ~~>[SMem] A(by * 32 + y, bx * 32 + x)"); + const __ghost_fn __ghost_pair_4 = __ghost_begin( + ro_group_focus, + "i := j * 16 + x, items := fun (x: int) -> " + "&tile[MINDEX3(exact_div(H, 32) * (exact_div(W, 32)), 32, " + "32, DMINDEX2(exact_div(H, 32), exact_div(W, 32), by, bx), " + "y, x)] ~~>[SMem] A(by * 32 + y, bx * 32 + x)"); + __ghost(assert_prop, "P := (H = exact_div(H, 32) * 32)", + "tile_div_check_y135 <- proof"); + __ghost(tiled_index_in_range, + "tile_index := by, index := y, div_check := " + "tile_div_check_y135"); + __ghost(tiled_index_in_range, + "tile_index := bx, index := j * 16 + x, div_check := " + "tile_div_check_x"); + __gmem_set( + &d_b[MINDEX2(W, H, bx * 32 + (j * 16 + x), by * 32 + y)], + __smem_get(&tile[MINDEX3( + exact_div(H, 32) * (exact_div(W, 32)), 32, 32, + DMINDEX2(exact_div(H, 32), exact_div(W, 32), by, bx), y, + j * 16 + x)])); __ghost_end(__ghost_pair_4); __ghost_end(__ghost_pair_5); } @@ -142,60 +319,132 @@ } kernel_teardown_begin(); __with("grid_sz := MSIZE4(exact_div(H, 32), exact_div(W, 32), 16, 32)"); - __barrier_sequence; { - __ghost(kernel_teardown_sync, "H := desync_for by in ..exact_div(H, 32) -> desync_for bx in ..exact_div(W, 32) -> for y in 0..32 -> for x in 0..32 -> &tile[MINDEX3(exact_div(H, 32) * (exact_div(W, 32)), 32, 32, DMINDEX2(exact_div(H, 32), exact_div(W, 32), by, bx), y, x)] ~~>[SMem] A(by * 32 + y, bx * 32 + x)"); - __ghost(kernel_teardown_sync, "H := desync_for by in ..exact_div(H, 32) -> desync_for bx in ..exact_div(W, 32) -> for j in 0..2 -> desync_for x in ..16 -> desync_for y in ..32 -> &d_b[MINDEX2(W, H, bx * 32 + (j * 16 + x), by * 32 + y)] ~~>[GMem] A(by * 32 + y, bx * 32 + (j * 16 + x))"); + __barrier_sequence; + { + __ghost(kernel_teardown_sync, + "H := desync_for by in ..exact_div(H, 32) -> desync_for bx in " + "..exact_div(W, 32) -> for y in 0..32 -> for x in 0..32 -> " + "&tile[MINDEX3(exact_div(H, 32) * (exact_div(W, 32)), 32, 32, " + "DMINDEX2(exact_div(H, 32), exact_div(W, 32), by, bx), y, x)] " + "~~>[SMem] A(by * 32 + y, bx * 32 + x)"); + __ghost( + kernel_teardown_sync, + "H := desync_for by in ..exact_div(H, 32) -> desync_for bx in " + "..exact_div(W, 32) -> for j in 0..2 -> desync_for x in ..16 -> " + "desync_for y in ..32 -> &d_b[MINDEX2(W, H, bx * 32 + (j * 16 + x), " + "by * 32 + y)] ~~>[GMem] A(by * 32 + y, bx * 32 + (j * 16 + x))"); } - for (int by = 0; by < exact_div(H, 32); by++) { + for (int by = 0; by < exact_div(H, 32); by++) { __strict(); - __xconsumes("for bx in 0..(exact_div(W, 32)) -> for j in 0..2 -> for x in 0..16 -> for y in 0..32 -> &d_b[MINDEX2(W, H, bx * 32 + (j * 16 + x), by * 32 + y)] ~~>[GMem] A(by * 32 + y, bx * 32 + (j * 16 + x))"); - __xproduces("for bx in 0..(exact_div(W, 32)) -> for x in 0..32 -> for y in 0..32 -> &d_b[MINDEX2(W, H, bx * 32 + x, by * 32 + y)] ~~>[GMem] A(by * 32 + y, bx * 32 + x)"); - for (int bx = 0; bx < exact_div(W, 32); bx++) { + __xconsumes( + "for bx in 0..(exact_div(W, 32)) -> for j in 0..2 -> for x in 0..16 " + "-> for y in 0..32 -> &d_b[MINDEX2(W, H, bx * 32 + (j * 16 + x), by " + "* 32 + y)] ~~>[GMem] A(by * 32 + y, bx * 32 + (j * 16 + x))"); + __xproduces( + "for bx in 0..(exact_div(W, 32)) -> for x in 0..32 -> for y in 0..32 " + "-> &d_b[MINDEX2(W, H, bx * 32 + x, by * 32 + y)] ~~>[GMem] A(by * " + "32 + y, bx * 32 + x)"); + for (int bx = 0; bx < exact_div(W, 32); bx++) { __strict(); - __xconsumes("for j in 0..2 -> for x in 0..16 -> for y in 0..32 -> &d_b[MINDEX2(W, H, bx * 32 + (j * 16 + x), by * 32 + y)] ~~>[GMem] A(by * 32 + y, bx * 32 + (j * 16 + x))"); - __xproduces("for x in 0..32 -> for y in 0..32 -> &d_b[MINDEX2(W, H, bx * 32 + x, by * 32 + y)] ~~>[GMem] A(by * 32 + y, bx * 32 + x)"); - __ghost(assert_prop, "P := (32 = 2 * 16)", "tile_div_check_y12 <- proof"); - __ghost(assert_prop, "P := (32 = 2 * 16)", "tile_div_check_x1113 <- proof"); - __ghost(untile_divides, "div_check := tile_div_check_x1113, items := fun (x: int) -> for y in 0..32 -> &d_b[MINDEX2(W, H, bx * 32 + x, by * 32 + y)] ~~>[GMem] A(by * 32 + y, bx * 32 + x)"); - __ghost(swap_groups, "outer_range := 0..32, inner_range := 0..32, items := fun (x: int) (y: int) -> &d_b[MINDEX2(W, H, bx * 32 + x, by * 32 + y)] ~~>[GMem] A(by * 32 + y, bx * 32 + x)"); - __ghost(swap_groups, "outer_range := 0..32, inner_range := 0..32, items := fun (y: int) (x: int) -> &d_b[MINDEX2(W, H, bx * 32 + x, by * 32 + y)] ~~>[GMem] A(by * 32 + y, bx * 32 + x)"); + __xconsumes( + "for j in 0..2 -> for x in 0..16 -> for y in 0..32 -> " + "&d_b[MINDEX2(W, H, bx * 32 + (j * 16 + x), by * 32 + y)] " + "~~>[GMem] A(by * 32 + y, bx * 32 + (j * 16 + x))"); + __xproduces( + "for x in 0..32 -> for y in 0..32 -> &d_b[MINDEX2(W, H, bx * 32 + " + "x, by * 32 + y)] ~~>[GMem] A(by * 32 + y, bx * 32 + x)"); + __ghost(assert_prop, "P := (32 = 2 * 16)", + "tile_div_check_y12 <- proof"); + __ghost(assert_prop, "P := (32 = 2 * 16)", + "tile_div_check_x1113 <- proof"); + __ghost(untile_divides, + "div_check := tile_div_check_x1113, items := fun (x: int) -> " + "for y in 0..32 -> &d_b[MINDEX2(W, H, bx * 32 + x, by * 32 + " + "y)] ~~>[GMem] A(by * 32 + y, bx * 32 + x)"); + __ghost(swap_groups, + "outer_range := 0..32, inner_range := 0..32, items := fun (x: " + "int) (y: int) -> &d_b[MINDEX2(W, H, bx * 32 + x, by * 32 + " + "y)] ~~>[GMem] A(by * 32 + y, bx * 32 + x)"); + __ghost(swap_groups, + "outer_range := 0..32, inner_range := 0..32, items := fun (y: " + "int) (x: int) -> &d_b[MINDEX2(W, H, bx * 32 + x, by * 32 + " + "y)] ~~>[GMem] A(by * 32 + y, bx * 32 + x)"); } } - __ghost(dmindex2_tile, "H := fun (f: int * int -> int) -> for di1 in 0..(exact_div(H, 32)) -> for di2 in 0..(exact_div(W, 32)) -> for i1 in 0..32 -> for i2 in 0..32 -> &tile[MINDEX3(exact_div(H, 32) * (exact_div(W, 32)), 32, 32, f(di1, di2), i1, i2)] ~> UninitCellOf(SMem), n1 := exact_div(H, 32), n2 := exact_div(W, 32)"); - __ghost(untile_divides, "items := fun (di: int) -> for i1 in 0..32 -> for i2 in 0..32 -> &tile[MINDEX3(exact_div(H, 32) * (exact_div(W, 32)), 32, 32, DMINDEX1(exact_div(H, 32) * (exact_div(W, 32)), di), i1, i2)] ~> UninitCellOf(SMem), div_check := eq_refl(exact_div(H, 32) * (exact_div(W, 32))), tile_count := exact_div(H, 32), tile_size := exact_div(W, 32)"); - __ghost(rewrite_linear, "from := exact_div(H, 32) * (exact_div(W, 32)), to := MSIZE2(exact_div(H, 32), exact_div(W, 32)), inside := fun (sz: int) -> for i in 0..sz -> for i1 in 0..32 -> for i2 in 0..32 -> &tile[MINDEX3(sz, 32, 32, DMINDEX1(sz, i), i1, i2)] ~> UninitCellOf(SMem)"); + __ghost( + dmindex2_tile, + "H := fun (f: int * int -> int) -> desync_for di1 in ..exact_div(H, " + "32) -> desync_for di2 in ..exact_div(W, 32) -> for i1 in 0..32 -> for " + "i2 in 0..32 -> &tile[MINDEX3(exact_div(H, 32) * (exact_div(W, 32)), " + "32, 32, f(di1, di2), i1, i2)] ~> UninitCellOf(SMem), n1 := " + "exact_div(H, 32), n2 := exact_div(W, 32)"); + __ghost(desync_untile_divides, + "items := fun (di: int) -> for i1 in 0..32 -> for i2 in 0..32 -> " + "&tile[MINDEX3(exact_div(H, 32) * (exact_div(W, 32)), 32, 32, " + "DMINDEX1(exact_div(H, 32) * (exact_div(W, 32)), di), i1, i2)] ~> " + "UninitCellOf(SMem), div_check := eq_refl(exact_div(H, 32) * " + "(exact_div(W, 32))), tile_count := exact_div(H, 32), tile_size := " + "exact_div(W, 32)"); + __ghost(rewrite_linear, + "from := exact_div(H, 32) * (exact_div(W, 32)), to := " + "MSIZE2(exact_div(H, 32), exact_div(W, 32)), inside := fun (sz: " + "int) -> desync_for i in ..sz -> for i1 in 0..32 -> for i2 in " + "0..32 -> &tile[MINDEX3(sz, 32, 32, DMINDEX1(sz, i), i1, i2)] ~> " + "UninitCellOf(SMem)"); __smem_free2(tile, 32, 32); - __ghost(swap_groups, "outer_range := 0..(exact_div(H, 32)), inner_range := 0..(exact_div(W, 32)), items := fun (by: int) (bx: int) -> for x in 0..32 -> for y in 0..32 -> &d_b[MINDEX2(W, H, bx * 32 + x, by * 32 + y)] ~~>[GMem] A(by * 32 + y, bx * 32 + x)"); - for (int bx = 0; bx < exact_div(W, 32); bx++) { + __ghost(swap_groups, + "outer_range := 0..(exact_div(H, 32)), inner_range := " + "0..(exact_div(W, 32)), items := fun (by: int) (bx: int) -> for x " + "in 0..32 -> for y in 0..32 -> &d_b[MINDEX2(W, H, bx * 32 + x, by " + "* 32 + y)] ~~>[GMem] A(by * 32 + y, bx * 32 + x)"); + for (int bx = 0; bx < exact_div(W, 32); bx++) { __strict(); - __xconsumes("for by in 0..(exact_div(H, 32)) -> for x in 0..32 -> for y in 0..32 -> &d_b[MINDEX2(W, H, bx * 32 + x, by * 32 + y)] ~~>[GMem] A(by * 32 + y, bx * 32 + x)"); - __xproduces("for x in 0..32 -> for y in 0..H -> &d_b[MINDEX2(W, H, bx * 32 + x, y)] ~~>[GMem] A(y, bx * 32 + x)"); - __ghost(swap_groups, "outer_range := 0..(exact_div(H, 32)), inner_range := 0..32, items := fun (by: int) (x: int) -> for y in 0..32 -> &d_b[MINDEX2(W, H, bx * 32 + x, by * 32 + y)] ~~>[GMem] A(by * 32 + y, bx * 32 + x)"); - for (int x = 0; x < 32; x++) { + __xconsumes( + "for by in 0..(exact_div(H, 32)) -> for x in 0..32 -> for y in 0..32 " + "-> &d_b[MINDEX2(W, H, bx * 32 + x, by * 32 + y)] ~~>[GMem] A(by * " + "32 + y, bx * 32 + x)"); + __xproduces( + "for x in 0..32 -> for y in 0..H -> &d_b[MINDEX2(W, H, bx * 32 + x, " + "y)] ~~>[GMem] A(y, bx * 32 + x)"); + __ghost( + swap_groups, + "outer_range := 0..(exact_div(H, 32)), inner_range := 0..32, items " + ":= fun (by: int) (x: int) -> for y in 0..32 -> &d_b[MINDEX2(W, H, " + "bx * 32 + x, by * 32 + y)] ~~>[GMem] A(by * 32 + y, bx * 32 + x)"); + for (int x = 0; x < 32; x++) { __strict(); - __xconsumes("for by in 0..(exact_div(H, 32)) -> for y in 0..32 -> &d_b[MINDEX2(W, H, bx * 32 + x, by * 32 + y)] ~~>[GMem] A(by * 32 + y, bx * 32 + x)"); - __xproduces("for y in 0..H -> &d_b[MINDEX2(W, H, bx * 32 + x, y)] ~~>[GMem] A(y, bx * 32 + x)"); - __ghost(assert_prop, "P := (H = exact_div(H, 32) * 32)", "tile_div_check_y12 <- proof"); - __ghost(untile_divides, "div_check := tile_div_check_y12, items := fun (y: int) -> &d_b[MINDEX2(W, H, bx * 32 + x, y)] ~~>[GMem] A(y, bx * 32 + x)"); + __xconsumes( + "for by in 0..(exact_div(H, 32)) -> for y in 0..32 -> " + "&d_b[MINDEX2(W, H, bx * 32 + x, by * 32 + y)] ~~>[GMem] A(by * 32 " + "+ y, bx * 32 + x)"); + __xproduces( + "for y in 0..H -> &d_b[MINDEX2(W, H, bx * 32 + x, y)] ~~>[GMem] " + "A(y, bx * 32 + x)"); + __ghost(assert_prop, "P := (H = exact_div(H, 32) * 32)", + "tile_div_check_y12 <- proof"); + __ghost( + untile_divides, + "div_check := tile_div_check_y12, items := fun (y: int) -> " + "&d_b[MINDEX2(W, H, bx * 32 + x, y)] ~~>[GMem] A(y, bx * 32 + x)"); } } __ghost(give_smem_token, "tok_sz := sizeof(float) * (32 * 32)"); kernel_kill(); - }/*kernel_sequence@*/ - __ghost(untile_divides, "div_check := tile_div_check_x, items := fun (x: int) -> for y in 0..H -> &d_b[MINDEX2(W, H, x, y)] ~~>[GMem] A(y, x)"); + } /*kernel_sequence@*/ + __ghost(untile_divides, + "div_check := tile_div_check_x, items := fun (x: int) -> for y in " + "0..H -> &d_b[MINDEX2(W, H, x, y)] ~~>[GMem] A(y, x)"); memcpy_device_to_host2(b, d_b, W, H); - __ghost([&] () { + __ghost([&]() { __preserves("d_b ~> UninitMatrix2Of(W, H, GMem)"); __admitted(); __with("justif := shift_groups"); }); gmem_free(d_b); - __ghost([&] () { + __ghost([&]() { __preserves("d_a ~> UninitMatrix2Of(H, W, GMem)"); __admitted(); __with("justif := shift_groups"); }); gmem_free(d_a); } - - diff --git a/lib/framework/resources/resource_computation.ml b/lib/framework/resources/resource_computation.ml index 151e4c682..99f232cde 100644 --- a/lib/framework/resources/resource_computation.ml +++ b/lib/framework/resources/resource_computation.ml @@ -477,6 +477,10 @@ let subtract_linear_resource_item ~(split_frac: bool) ((x, formula): resource_it (fun inner_formula idx dim inner_formula_candidate () -> formula_desyncgroup idx dim (may_coerce_desyncgroup inner_formula_candidate inner_formula) ); + Pattern.((formula_group __ __ !__) ^* (formula_group !__ !__ !__)) + (fun inner_formula idx range inner_formula_candidate () -> + formula_group idx range (may_coerce_desyncgroup inner_formula_candidate inner_formula) + ); Pattern.__ (fun () -> formula_candidate) ] in @@ -1260,6 +1264,8 @@ let sync_simplification ?(magic = false) (res: resource_set): resource_set = let rec simplify (mem_fn: trm) (t: trm) = Pattern.pattern_match t [ Pattern.(formula_group !__ !__ !__) (fun idx range sub () -> formula_group idx range (simplify mem_fn sub)); + Pattern.(formula_If !__ !__) (fun cond h () -> + formula_If cond (simplify mem_fn h)); Pattern.(formula_desyncgroup !__ !__ !__) (fun idx bound sub () -> formula_group idx (formula_range (trm_int 0) bound (trm_int 1)) (simplify mem_fn sub)); Pattern.(formula_points_to !__ !__ !__) (fun var model mem_typ () -> diff --git a/lib/framework/resources/resource_formula.ml b/lib/framework/resources/resource_formula.ml index acdf31651..ebfff6cf2 100644 --- a/lib/framework/resources/resource_formula.ml +++ b/lib/framework/resources/resource_formula.ml @@ -328,6 +328,15 @@ let formula_desyncgroup_inv (t: trm): (var * trm * formula) option = end | _ -> None +let var_formula_If = toplevel_var "If" +let formula_If (cond: formula) (h: formula) = trm_apps ~annot:formula_annot ~typ:typ_hprop (trm_var var_formula_If) [cond; h] + +let formula_If_inv (t: trm): (formula * formula) option = + match trm_apps_inv t with + | Some ({ desc = Trm_var v }, [cond; h]) when var_eq v var_formula_If -> + Some (cond, h) + | _ -> None + let var_threadsctx = toplevel_var "ThreadsCtx" let trm_threadsctx = trm_var var_threadsctx @@ -484,6 +493,14 @@ module Pattern = struct k | None -> raise Next + let formula_If f_cond f_h k t = + match formula_If_inv t with + | Some (cond, h) -> + let k = f_cond k cond in + let k = f_h k h in + k + | None -> raise Next + let formula_range (f_begin: 'a -> trm -> 'b) (f_end: 'b -> trm -> 'c) (f_step: 'c -> trm -> 'd) = trm_apps3 (trm_specific_var var_range) f_begin f_end f_step diff --git a/lib/framework/resources/resource_trm.ml b/lib/framework/resources/resource_trm.ml index 802dec4de..96c935f2c 100644 --- a/lib/framework/resources/resource_trm.ml +++ b/lib/framework/resources/resource_trm.ml @@ -222,6 +222,24 @@ let var_ghost_unwrap_singleton_desyncgroup = toplevel_var "unwrap_singleton_desy let ghost_unwrap_singleton_desyncgroup ?(formula : formula option) () = ghost (ghost_call_opt_args var_ghost_unwrap_singleton_desyncgroup ["H", formula]) +let ghost_var_if_false_hprop_rewrite = toplevel_var "if_false_hprop_rewrite" +let ghost_var_if_true_hprop_elim = toplevel_var "if_true_hprop_elim" +let ghost_var_if_true_hprop_intro = toplevel_var "if_true_hprop_intro" +let ghost_var_if_false_hprop_drop = toplevel_var "if_false_hprop_drop" + +let ghost_if_false_hprop_rewrite ?b from into = + ghost (ghost_call_opt_args (ghost_var_if_false_hprop_rewrite) (["b",b; "H",Some from; "H2",Some into])) + +let ghost_if_false_hprop_drop ?b h = + ghost (ghost_call_opt_args (ghost_var_if_false_hprop_drop) (["b",b; "H",Some h])) + +let ghost_if_true_hprop_elim ?b ?hp h = + ghost (ghost_call_opt_args (ghost_var_if_true_hprop_elim) (["b",b; "HP",hp; "H",Some h])) + +let ghost_if_true_hprop_intro ?b ?hp h = + ghost (ghost_call_opt_args (ghost_var_if_true_hprop_intro) (["b",b; "HP",hp; "H",Some h])) + + let var_arbitrary = toplevel_var "arbitrary" let var_admit = toplevel_var "admit" diff --git a/lib/transfo/gpu.ml b/lib/transfo/gpu.ml index 877188968..f0b3b774d 100644 --- a/lib/transfo/gpu.ml +++ b/lib/transfo/gpu.ml @@ -64,7 +64,7 @@ let%transfo convert_to_global_mem (tg: target): unit = Target.iter (fun p -> let _,tg_seq_p = Path.index_in_seq p in Resources.with_non_strict_loop_contracts [cPath tg_seq_p] (fun () -> - Gpu_basic.convert_memory Gpu_basic.gmem_spec [cPath p] + Gpu_basic.convert_memory Gpu_basic.gmem_spec [cPath p]; ) ) tg @@ -80,8 +80,10 @@ let%transfo convert_to_shared_mem ~(chop_dims: int) (tg: target): unit = let free_mark = next_m () in Gpu_basic.convert_memory (Gpu_basic.smem_spec ~alloc_mark ~free_mark chop_dims) tg; let aliases = ref Var_set.empty in - let kernel_seq = [tSpan [cMark alloc_mark] [cMark free_mark]] in - Gpu_basic.fix_distrib_accesses ~aliases chop_dims kernel_seq tg; + (* FIXME: support multiple kernels *) + Gpu_basic.fix_distrib_accesses ~aliases ~synced:true chop_dims [tSpan [cMark alloc_mark] [tBefore; cCall "kernel_setup_end"]] tg; + Gpu_basic.fix_distrib_accesses ~aliases chop_dims [tSpan [tAfter; cCall "kernel_setup_end"] [tBefore; cCall "kernel_teardown_begin"]] tg; + Gpu_basic.fix_distrib_accesses ~aliases ~synced:true chop_dims [tSpan [tAfter; cCall "kernel_teardown_begin"] [cMark free_mark]] tg; Var_set.iter (fun alias -> Gpu_basic.convert_memory (Gpu_basic.smem_alias_spec alias) tg; ) !aliases; @@ -99,8 +101,12 @@ let%transfo convert_to_register_mem ~(chop_dims: int) (tg: target): unit = let free_mark = next_m () in Gpu_basic.convert_memory (Gpu_basic.treg_mem_spec ~alloc_mark ~free_mark chop_dims) tg; let aliases = ref Var_set.empty in - let kernel_seq = [tSpan [cMark alloc_mark] [cMark free_mark]] in - Gpu_basic.fix_distrib_accesses ~aliases chop_dims kernel_seq tg; + Gpu_basic.fix_distrib_accesses ~aliases chop_dims [tSpan [cMark alloc_mark] [cMark free_mark]] tg; + (* TODO ? + (* FIXME: support multiple kernels *) + Gpu_basic.fix_distrib_accesses ~aliases ~synced:true chop_dims [tSpan [cMark alloc_mark] [tBefore; cCall "kernel_setup_end"]] tg; + Gpu_basic.fix_distrib_accesses ~aliases chop_dims [tSpan [tAfter; cCall "kernel_setup_end"] [tBefore; cCall "kernel_teardown_begin"]] tg; + Gpu_basic.fix_distrib_accesses ~aliases ~synced:true chop_dims [tSpan [tAfter; cCall "kernel_teardown_begin"] [cMark free_mark]] tg; *) Var_set.iter (fun alias -> Gpu_basic.convert_memory (Gpu_basic.treg_mem_alias_spec alias) tg; ) !aliases; diff --git a/lib/transfo/gpu_basic.ml b/lib/transfo/gpu_basic.ml index c0c18272a..9c6dfa5c1 100644 --- a/lib/transfo/gpu_basic.ml +++ b/lib/transfo/gpu_basic.ml @@ -243,7 +243,7 @@ let to_desync_for (tg: target): unit = (** [fix_distrib_accesses] fixes distributed dimensions: e.g. if a 4D buffer declared at the kernel level is converted to shared memory, and there are 2 dimensions of blocks, then there are now 2 distributed dimensions. This function would convert all instances of MINDEX4(...) on that variable to MINDEX3(DMINDEX2(...), ...). *) -let fix_distrib_accesses ~(aliases: Var_set.t ref) (chop_dims: int) (body_span_tg: target) (alloc_tg: target): unit = +let fix_distrib_accesses ~(aliases: Var_set.t ref) ?(synced = false) (chop_dims: int) (body_span_tg: target) (alloc_tg: target): unit = if chop_dims = 0 then () else begin let body_seq_path,body_seq_span = Target.resolve_target_span_exactly_one body_span_tg in @@ -277,7 +277,7 @@ let fix_distrib_accesses ~(aliases: Var_set.t ref) (chop_dims: int) (body_span_t let body = aux (threadfor_depth + 1) body in (* LATER: better heuristics to convert the desyncgroups if ghosts are being used on these dimensions *) let probably_distributed = chop_dims - threadfor_depth > 0 in - if probably_distributed then + if (not synced) && probably_distributed then formula_desyncgroup ind stop body else formula_group ind range body diff --git a/lib/transfo/loop_basic.ml b/lib/transfo/loop_basic.ml index 4b3165a8b..863e4ee57 100644 --- a/lib/transfo/loop_basic.ml +++ b/lib/transfo/loop_basic.ml @@ -1471,27 +1471,6 @@ let ghost_group_intro_one item = let ghost_group_elim_one item = Resource_trm.ghost (ghost_call (ghost_var_group_elim_one) (["item", item])) -(* TODO: move elsewhere *) -let var_formula_If = toplevel_var "If" -let formula_If (cond: formula) (h: formula) = (trm_apps ~annot:Resource_formula.formula_annot ~typ:typ_hprop (trm_var var_formula_If) [cond; h]) - -let ghost_var_if_false_hprop_rewrite = toplevel_var "if_false_hprop_rewrite" -let ghost_var_if_true_hprop_elim = toplevel_var "if_true_hprop_elim" -let ghost_var_if_true_hprop_intro = toplevel_var "if_true_hprop_intro" -let ghost_var_if_false_hprop_drop = toplevel_var "if_false_hprop_drop" - -let ghost_if_false_hprop_rewrite ?b from into = - Resource_trm.ghost (Resource_trm.ghost_call_opt_args (ghost_var_if_false_hprop_rewrite) (["b",b; "H",Some from; "H2",Some into])) - -let ghost_if_false_hprop_drop ?b h = - Resource_trm.ghost (Resource_trm.ghost_call_opt_args (ghost_var_if_false_hprop_drop) (["b",b; "H",Some h])) - -let ghost_if_true_hprop_elim ?b ?hp h = - Resource_trm.ghost (Resource_trm.ghost_call_opt_args (ghost_var_if_true_hprop_elim) (["b",b; "HP",hp; "H",Some h])) - -let ghost_if_true_hprop_intro ?b ?hp h = - Resource_trm.ghost (Resource_trm.ghost_call_opt_args (ghost_var_if_true_hprop_intro) (["b",b; "HP",hp; "H",Some h])) - (* LATER: refactor with other loop/if transfos such as expand_range, fold, etc. modify those to support contracts/models like this one. *) let%transfo intro_loop_single_on ?(index: string = "t") (bound: trm) (start_tg: target) (stop_tg: target) = @@ -1568,18 +1547,18 @@ let%transfo intro_loop_single_on ?(index: string = "t") (bound: trm) (start_tg: let if_cond_proof_var = new_var (fresh_var_name ~prefix:"Hcond" ()) in let then_elim_ghosts = List.map (fun (_,f) -> - ghost_if_true_hprop_elim ~hp:(trm_var if_cond_proof_var) f + Resource_trm.ghost_if_true_hprop_elim ~hp:(trm_var if_cond_proof_var) f ) !before in let then_intro_ghosts = List.map (fun (_,f) -> - ghost_if_true_hprop_intro ~hp:(trm_var if_cond_proof_var) f + Resource_trm.ghost_if_true_hprop_intro ~hp:(trm_var if_cond_proof_var) f ) !after in assert (List.length !before >= List.length !after); (* only one case handled for now *) let before_rewrite,before_drop = List.split_at (List.length !after) !before in let else_ghosts = List.map2 (fun (_,f1) (_,f2) -> - ghost_if_false_hprop_rewrite f1 f2 + Resource_trm.ghost_if_false_hprop_rewrite f1 f2 ) before_rewrite !after in let else_ghosts = else_ghosts @ (List.map (fun (_,f) -> - ghost_if_false_hprop_drop f) before_drop) in + Resource_trm.ghost_if_false_hprop_drop f) before_drop) in let assert_if_cond = Resource_trm.ghost_assert if_cond_proof_var (formula_eq ~typ:typ_int (trm_var range.index) (trm_int 0)) in From 620f42b0ba45845842e489fa136d82d94c790c81 Mon Sep 17 00:00:00 2001 From: Thomas Koehler Date: Fri, 10 Jul 2026 17:53:58 +0200 Subject: [PATCH 10/23] flag bug --- case_studies/gpu/reduction/reduce.ml | 3 ++- case_studies/gpu/transpose/transpose.ml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/case_studies/gpu/reduction/reduce.ml b/case_studies/gpu/reduction/reduce.ml index 41f02e821..1ca030e56 100644 --- a/case_studies/gpu/reduction/reduce.ml +++ b/case_studies/gpu/reduction/reduce.ml @@ -5,7 +5,7 @@ let _ = Flags.check_validity := true let _ = Flags.use_resources_with_models := true let _ = Flags.preserve_specs_only := true let _ = Flags.pretty_matrix_notation := false -let _ = Flags.recompute_resources_between_steps := false +let _ = Flags.recompute_resources_between_steps := true (* FIXME: should be false *) let _ = Flags.disable_stringreprs := true let _ = Flags.save_ast_for_steps := Some Flags.Steps_script (* Some Flags.Steps_important *) let _ = Flags.only_big_steps := true @@ -183,6 +183,7 @@ let _ = Run.script_cpp_stage stage_ok (fun () -> But it's also not declared on the host level. Normally, having a variable as thread for loop bounds is illegal, but this is just a pure constant, so it can be inlined as a quick fix to the problem. *) !! Variable.inline [cVarDef ~regexp:true "N.+"]; + !! Flags.recompute_resources_between_steps := false; !! Trace.without_substep_validity_checks (fun () -> Instr.move ~dest:[tFirst; cMark "kernel_sequence"] [cCall "kernel_launch"]; Trace.generate_cuda ~check_expected:true (); diff --git a/case_studies/gpu/transpose/transpose.ml b/case_studies/gpu/transpose/transpose.ml index ee44c8eef..dad44dc94 100644 --- a/case_studies/gpu/transpose/transpose.ml +++ b/case_studies/gpu/transpose/transpose.ml @@ -4,7 +4,7 @@ open Prelude let _ = Flags.check_validity := true let _ = Flags.recompute_resources_between_steps := false let _ = Flags.disable_stringreprs := true -let _ = Flags.save_ast_for_steps := Some Flags.Steps_important +let _ = Flags.save_ast_for_steps := None (* Some Flags.Steps_important *) let _ = Flags.pretty_matrix_notation := false let stage_ok = fun i -> true (* i = 5 *) From 2209c46a7328acff3c2cf81c7277338386e1f2dc Mon Sep 17 00:00:00 2001 From: "yanni.lefki" Date: Mon, 20 Jul 2026 15:23:32 +0200 Subject: [PATCH 11/23] [WIP] cleaning flags --- case_studies/clift/demo/demo_no_verif.ml | 4 +- case_studies/clift/demo/demo_verif.ml | 3 +- case_studies/clift/demo/loop_swap.ml | 3 +- .../clift/quantization/access_scale.ml | 5 +- .../clift/quantization/matvec_to_quantize.ml | 3 +- case_studies/clift/verif/kernels.ml | 3 +- case_studies/dot_product/dot.ml | 5 +- case_studies/floyd_warshall/floyd_warshall.ml | 1 + case_studies/gpu/histogram/hist.ml | 3 +- case_studies/gpu/matmul/matmul.ml | 3 +- case_studies/gpu/reduction/reduce.ml | 7 +- case_studies/gpu/transpose/transpose.ml | 3 +- case_studies/gpu/transpose/transpose_gpu.ml | 3 +- case_studies/gpu/vector_add/vector_add.ml | 3 +- case_studies/matmul/matmul.ml | 2 +- case_studies/matmul/matmul_check.ml | 5 +- case_studies/matmul/matmul_models.ml | 3 +- case_studies/minipic/fixed_tmp_micropic.ml | 5 +- case_studies/minipic/micropic.ml | 5 +- case_studies/opencv/box_filter_rowsum.ml | 5 +- .../box_filter_rowsum_before_cleanup.ml | 5 +- .../opencv/box_filter_rowsum_models.ml | 3 +- .../opencv/box_filter_rowsum_models_end.ml | 3 +- .../tuto/reduction_reinit/reduction_reinit.ml | 3 +- case_studies/tuto/skewing/skewing.ml | 3 +- case_studies/tuto/stencil/stencil1D.ml | 3 +- lib/framework/flags.ml | 44 ++++++++-- lib/framework/resources.ml | 18 ++-- lib/framework/runtime/run.ml | 2 +- lib/framework/runtime/trace.ml | 32 ++++--- lib/transfo/accesses_basic.ml | 14 ++-- lib/transfo/arith_basic.ml | 5 +- lib/transfo/arith_core.ml | 4 +- lib/transfo/arrays.ml | 2 + lib/transfo/arrays_basic.ml | 6 ++ lib/transfo/function.ml | 2 +- lib/transfo/function_basic.ml | 2 +- lib/transfo/function_core.ml | 14 ++-- lib/transfo/ghost_pair.ml | 3 + lib/transfo/ghost_pure.ml | 1 + lib/transfo/gpu.ml | 2 +- lib/transfo/gpu_basic.ml | 1 + lib/transfo/if_basic.ml | 6 +- lib/transfo/instr.ml | 5 +- lib/transfo/instr_basic.ml | 5 +- lib/transfo/label_basic.ml | 1 + lib/transfo/loop.ml | 10 +-- lib/transfo/loop_basic.ml | 47 ++++++----- lib/transfo/loop_core.ml | 6 +- lib/transfo/loop_swap.ml | 10 +-- lib/transfo/matrix.ml | 6 ++ lib/transfo/matrix_basic.ml | 12 ++- lib/transfo/omp_basic.ml | 84 ++++++++++++++++++- lib/transfo/record.ml | 1 + lib/transfo/record_basic.ml | 23 +++-- lib/transfo/record_core.ml | 10 +-- lib/transfo/reduce.ml | 50 ++++++----- lib/transfo/sequence_basic.ml | 4 +- lib/transfo/sequence_core.ml | 5 +- lib/transfo/stencil.ml | 3 + lib/transfo/typedef_basic.ml | 1 + lib/transfo/variable.ml | 2 + lib/transfo/variable_basic.ml | 78 ++++++++--------- tests/accesses/scale/accesses_scale_basic.ml | 3 +- tests/accesses/scale/accesses_scale_doc.ml | 5 +- tests/accesses/shift/accesses_shift_models.ml | 8 +- 66 files changed, 426 insertions(+), 205 deletions(-) diff --git a/case_studies/clift/demo/demo_no_verif.ml b/case_studies/clift/demo/demo_no_verif.ml index a45dbfe6e..60a8cdf22 100644 --- a/case_studies/clift/demo/demo_no_verif.ml +++ b/case_studies/clift/demo/demo_no_verif.ml @@ -1,8 +1,10 @@ +(* Deprecated *) + open Optitrust open Prelude let _ = - Flags.check_validity := false; + (* Flags.check_validity := false; *) Flags.detailed_resources_in_trace := false; Flags.pretty_matrix_notation := true diff --git a/case_studies/clift/demo/demo_verif.ml b/case_studies/clift/demo/demo_verif.ml index 373427d6e..d1ab521d2 100644 --- a/case_studies/clift/demo/demo_verif.ml +++ b/case_studies/clift/demo/demo_verif.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Prelude let _ = - Flags.check_validity := true; + (* Flags.check_validity := true; *) (* Flags.detailed_resources_in_trace := true; *) Flags.save_ast_for_steps := Some Steps_important diff --git a/case_studies/clift/demo/loop_swap.ml b/case_studies/clift/demo/loop_swap.ml index 835adef7f..7680a1dd3 100644 --- a/case_studies/clift/demo/loop_swap.ml +++ b/case_studies/clift/demo/loop_swap.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Prelude let _ = - Flags.check_validity := true; + (* Flags.check_validity := true; *) Flags.detailed_resources_in_trace := true; Flags.save_ast_for_steps := Some Steps_all diff --git a/case_studies/clift/quantization/access_scale.ml b/case_studies/clift/quantization/access_scale.ml index 6ec310d87..145c6648b 100644 --- a/case_studies/clift/quantization/access_scale.ml +++ b/case_studies/clift/quantization/access_scale.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) let insert_max_tab_on (tab : typed_var) (size : trm) (i : int) (t : trm) : trm = let v, typ = tab in diff --git a/case_studies/clift/quantization/matvec_to_quantize.ml b/case_studies/clift/quantization/matvec_to_quantize.ml index 23cf7a804..e73e4e596 100644 --- a/case_studies/clift/quantization/matvec_to_quantize.ml +++ b/case_studies/clift/quantization/matvec_to_quantize.ml @@ -1,10 +1,11 @@ +(* Deprecated *) open Optitrust open Prelude let _ = Flags.pretty_matrix_notation := true; Flags.print_optitrust_syntax := true; - Flags.check_validity := false + (* Flags.check_validity := false *) let reconstruct_seq (lbefore : trm mlist) (t : trm) (lafter : trm mlist) : trm = let new_lbefore = Mlist.push_back t lbefore in diff --git a/case_studies/clift/verif/kernels.ml b/case_studies/clift/verif/kernels.ml index cbc274958..fbdc42edf 100644 --- a/case_studies/clift/verif/kernels.ml +++ b/case_studies/clift/verif/kernels.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Prelude let _ = - Flags.check_validity := true;Flags.detailed_resources_in_trace := true; + (* Flags.check_validity := true; *)Flags.detailed_resources_in_trace := true; Flags.save_ast_for_steps := Some Steps_all let _ = Run.script_cpp ( fun x -> !!!()); diff --git a/case_studies/dot_product/dot.ml b/case_studies/dot_product/dot.ml index e9f0eba12..243cdb2a2 100644 --- a/case_studies/dot_product/dot.ml +++ b/case_studies/dot_product/dot.ml @@ -1,9 +1,10 @@ open Optitrust open Prelude -let _ = Flags.check_validity := true (* FIXME: false *) +(* let _ = Flags.check_validity := true (* FIXME: false *) *) +let _ = Flags.typechecking_mode := Flags.AnnotatedAndVerified let _ = Flags.use_resources_with_models := true -let _ = Flags.preserve_specs_only := true +(* let _ = Flags.preserve_specs_only := true *) let _ = Flags.pretty_matrix_notation := false let _ = Flags.recompute_resources_between_steps := true let _ = Flags.disable_stringreprs := true diff --git a/case_studies/floyd_warshall/floyd_warshall.ml b/case_studies/floyd_warshall/floyd_warshall.ml index a5e9c8dec..46a3baf92 100644 --- a/case_studies/floyd_warshall/floyd_warshall.ml +++ b/case_studies/floyd_warshall/floyd_warshall.ml @@ -1,3 +1,4 @@ +(* Deprecated *) open Optitrust open Prelude diff --git a/case_studies/gpu/histogram/hist.ml b/case_studies/gpu/histogram/hist.ml index 6675fb6d9..f7d273f1c 100644 --- a/case_studies/gpu/histogram/hist.ml +++ b/case_studies/gpu/histogram/hist.ml @@ -1,7 +1,8 @@ open Optitrust open Prelude -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) +let _ = Flags.typechecking_mode := Flags.AnnotatedAndVerified let _ = Flags.pretty_matrix_notation := true let _ = Flags.recompute_resources_between_steps := true let _ = Flags.disable_stringreprs := true diff --git a/case_studies/gpu/matmul/matmul.ml b/case_studies/gpu/matmul/matmul.ml index fb4bff1b9..d2707799e 100644 --- a/case_studies/gpu/matmul/matmul.ml +++ b/case_studies/gpu/matmul/matmul.ml @@ -1,7 +1,8 @@ open Optitrust open Prelude -let _ = Flags.check_validity := true (* FIXME: this flag behaviour needs to be cleaned up *) +(* let _ = Flags.check_validity := true *) +let _ = Flags.typechecking_mode := Flags.AnnotatedAndVerified let _ = Flags.pretty_matrix_notation := false let _ = Flags.recompute_resources_between_steps := true let _ = Flags.disable_stringreprs := true diff --git a/case_studies/gpu/reduction/reduce.ml b/case_studies/gpu/reduction/reduce.ml index 73b4b6a4e..601970634 100644 --- a/case_studies/gpu/reduction/reduce.ml +++ b/case_studies/gpu/reduction/reduce.ml @@ -1,9 +1,10 @@ open Optitrust open Prelude -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Flags.use_resources_with_models := true -let _ = Flags.preserve_specs_only := true +(* let _ = Flags.preserve_specs_only := true *) +let _ = Flags.typechecking_mode := Flags.Annotated let _ = Flags.pretty_matrix_notation := false let _ = Flags.recompute_resources_between_steps := true let _ = Flags.disable_stringreprs := true @@ -115,7 +116,7 @@ let _ = Run.script_cpp_stage stage_ok (fun () -> let sum_tg = [cFunDef "reduce"; cFor "bi"; cFor "ti"; cArrayWrite "d_partial_sums"] in !! Ghost.flatten_expr_rewrites (sum_tg @ [dRHS]); !! replace_with_tree_reduce (trm_int log_tpb) sum_tg; - !! Flags.with_flag Flags.check_validity false (fun () -> Function.inline_def [cFunDef "tree_reduce"]); + !! Flags.with_flag (* Flags.check_validity false *) Flags.typechecking_mode Flags.Unverified (fun () -> Function.inline_def [cFunDef "tree_reduce"]); (* Mask writing of final result to only 1 thread *) !! Loop_basic.intro_loop_single_on ~index:"ti_f" (trm_int tpb) [tAfter; cFor "i" ~body:[cFor "t"]] [tAfter; occLast; cArrayWrite "d_partial_sums"]; diff --git a/case_studies/gpu/transpose/transpose.ml b/case_studies/gpu/transpose/transpose.ml index 17b5f1838..87ff4920f 100644 --- a/case_studies/gpu/transpose/transpose.ml +++ b/case_studies/gpu/transpose/transpose.ml @@ -1,7 +1,8 @@ open Optitrust open Prelude -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) +let _ = Flags.typechecking_mode := Flags.AnnotatedAndVerified let _ = Flags.recompute_resources_between_steps := true let _ = Flags.disable_stringreprs := true let _ = Flags.save_ast_for_steps := Some Flags.Steps_important diff --git a/case_studies/gpu/transpose/transpose_gpu.ml b/case_studies/gpu/transpose/transpose_gpu.ml index 311898e60..86cc78615 100644 --- a/case_studies/gpu/transpose/transpose_gpu.ml +++ b/case_studies/gpu/transpose/transpose_gpu.ml @@ -1,7 +1,8 @@ open Optitrust open Prelude -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) +let _ = Flags.typechecking_mode := Flags.AnnotatedAndVerified let _ = Flags.pretty_matrix_notation := true let _ = Flags.recompute_resources_between_steps := true let _ = Flags.disable_stringreprs := true diff --git a/case_studies/gpu/vector_add/vector_add.ml b/case_studies/gpu/vector_add/vector_add.ml index 1d365e158..6eff6b333 100644 --- a/case_studies/gpu/vector_add/vector_add.ml +++ b/case_studies/gpu/vector_add/vector_add.ml @@ -2,7 +2,8 @@ open Optitrust open Prelude open Cuda_lowering -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) +let _ = Flags.typechecking_mode := Flags.AnnotatedAndVerified let _ = Flags.pretty_matrix_notation := true let _ = Flags.recompute_resources_between_steps := false let _ = Flags.disable_stringreprs := true diff --git a/case_studies/matmul/matmul.ml b/case_studies/matmul/matmul.ml index 62557a7c1..91eef1332 100644 --- a/case_studies/matmul/matmul.ml +++ b/case_studies/matmul/matmul.ml @@ -1,8 +1,8 @@ +(* Deprecated *) open Optitrust open Prelude let _ = Flags.pretty_matrix_notation := true -let _ = Flags.disable_resource_typing () (* Reproducing a TVM schedule for matrix multiplication: 1. improve data locality by blocking the computation of C and preloading B with a packed memory layout diff --git a/case_studies/matmul/matmul_check.ml b/case_studies/matmul/matmul_check.ml index dfda4ed48..460c259b3 100644 --- a/case_studies/matmul/matmul_check.ml +++ b/case_studies/matmul/matmul_check.ml @@ -1,9 +1,10 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Flags.pretty_matrix_notation := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.recompute_resources_between_steps := true *) let _ = Flags.disable_stringreprs := true (* let _ = Flags.report_exectime := true *) diff --git a/case_studies/matmul/matmul_models.ml b/case_studies/matmul/matmul_models.ml index 94eee24d5..6989c5386 100644 --- a/case_studies/matmul/matmul_models.ml +++ b/case_studies/matmul/matmul_models.ml @@ -1,7 +1,8 @@ open Optitrust open Prelude -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) +let _ = Flags.typechecking_mode := Flags.AnnotatedAndVerified let _ = Flags.pretty_matrix_notation := true let _ = Flags.recompute_resources_between_steps := true let _ = Flags.disable_stringreprs := true diff --git a/case_studies/minipic/fixed_tmp_micropic.ml b/case_studies/minipic/fixed_tmp_micropic.ml index 04b5c4058..d9b44cde4 100644 --- a/case_studies/minipic/fixed_tmp_micropic.ml +++ b/case_studies/minipic/fixed_tmp_micropic.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true +let _ = Flags.recompute_resources_between_steps := true *) (** Reproducing a subset of the PIC case study *) diff --git a/case_studies/minipic/micropic.ml b/case_studies/minipic/micropic.ml index 8b219e406..bd23428a4 100644 --- a/case_studies/minipic/micropic.ml +++ b/case_studies/minipic/micropic.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true +let _ = Flags.recompute_resources_between_steps := true *) let _ = Flags.disable_stringreprs := true let _ = Flags.save_steps := Some Steps_script let _ = Flags.save_ast_for_steps := Some Steps_all diff --git a/case_studies/opencv/box_filter_rowsum.ml b/case_studies/opencv/box_filter_rowsum.ml index c0dc42589..faa6b835b 100644 --- a/case_studies/opencv/box_filter_rowsum.ml +++ b/case_studies/opencv/box_filter_rowsum.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true +let _ = Flags.recompute_resources_between_steps := true *) let _ = Flags.disable_stringreprs := true (* Generated trace is too heavy. Keep only the steps of the transformation script *) diff --git a/case_studies/opencv/box_filter_rowsum_before_cleanup.ml b/case_studies/opencv/box_filter_rowsum_before_cleanup.ml index 9bfac3eee..efdb55369 100644 --- a/case_studies/opencv/box_filter_rowsum_before_cleanup.ml +++ b/case_studies/opencv/box_filter_rowsum_before_cleanup.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true +let _ = Flags.recompute_resources_between_steps := true *) let _ = Flags.disable_stringreprs := true let _ = Run.script_cpp (fun () -> diff --git a/case_studies/opencv/box_filter_rowsum_models.ml b/case_studies/opencv/box_filter_rowsum_models.ml index 06adcdc08..6e32d39a6 100644 --- a/case_studies/opencv/box_filter_rowsum_models.ml +++ b/case_studies/opencv/box_filter_rowsum_models.ml @@ -1,8 +1,9 @@ open Optitrust open Prelude -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Flags.recompute_resources_between_steps := true +let _ = Flags.typechecking_mode := Flags.AnnotatedAndVerified let _ = Flags.disable_stringreprs := true (* Generated trace is too heavy. Keep only the steps of the transformation script *) diff --git a/case_studies/opencv/box_filter_rowsum_models_end.ml b/case_studies/opencv/box_filter_rowsum_models_end.ml index 405cb5e5f..9b8fbd716 100644 --- a/case_studies/opencv/box_filter_rowsum_models_end.ml +++ b/case_studies/opencv/box_filter_rowsum_models_end.ml @@ -1,7 +1,8 @@ open Optitrust open Prelude -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) +let _ = Flags.typechecking_mode := Flags.AnnotatedAndVerified let _ = Flags.disable_stringreprs := true (* Generated trace is too heavy. Keep only the steps of the transformation script *) diff --git a/case_studies/tuto/reduction_reinit/reduction_reinit.ml b/case_studies/tuto/reduction_reinit/reduction_reinit.ml index 99938aff9..d6642ff47 100644 --- a/case_studies/tuto/reduction_reinit/reduction_reinit.ml +++ b/case_studies/tuto/reduction_reinit/reduction_reinit.ml @@ -1,6 +1,7 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := false +(* let _ = Flags.check_validity := false *) let delocalize_sum = Local_arith (Lit_float (typ_f64,0.) , Binop_add) let _ = Run.script_cpp (fun _ -> diff --git a/case_studies/tuto/skewing/skewing.ml b/case_studies/tuto/skewing/skewing.ml index dcf392fe4..ce4c3fc50 100644 --- a/case_studies/tuto/skewing/skewing.ml +++ b/case_studies/tuto/skewing/skewing.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := false +(* let _ = Flags.check_validity := false *) let _ = Run.script_cpp (fun _ -> diff --git a/case_studies/tuto/stencil/stencil1D.ml b/case_studies/tuto/stencil/stencil1D.ml index d2a8def36..e7121caaf 100644 --- a/case_studies/tuto/stencil/stencil1D.ml +++ b/case_studies/tuto/stencil/stencil1D.ml @@ -1,6 +1,7 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := false +(* let _ = Flags.check_validity := false *) let _ = Run.script_cpp (fun _ -> !! Loop.fission [cForBody "i"; tBefore; dSeqNth 1];) diff --git a/lib/framework/flags.ml b/lib/framework/flags.ml index 7ddf0824b..9079266d0 100644 --- a/lib/framework/flags.ml +++ b/lib/framework/flags.ml @@ -21,7 +21,7 @@ let analyse_stats_details : bool ref = ref false (** [dump_ast_details]: flag to dump OptiTrust AST, both in the form of a '.ast' and '_enc.cpp' files. *) let dump_ast_details : bool ref = ref false -(* TODO : deprecate once optilambda surface display works *) +(* TODO Yanni : deprecate once optilambda surface display works *) (** [pretty_matrix_notation]: flag to display matrix macros with syntactic sugar: MALLOC2(n, m, sizeof(T)) --> malloc(sizeof(T[n][m])) x[MINDEX2(n, m, i, j)] --> x[i;j] @@ -90,9 +90,9 @@ let clang_format_nb_columns : int ref = ref 80 (** [code_print_width]: flag to choose the width of the printed code on stdout. *) let code_print_width = ref 80 +(* TODO: could it be true by default? *) (** [use_light_diff]: flag to enable "light diffs", whereby we hide the function body of all the toplevel functions that are not affected by the transformation. *) - (* TODO: could it be true by default? *) let use_light_diff : bool ref = ref false (** [bypass_cfeatures]: flag used for debugging the [decode_from_c/intro] functions, by bypassing them. @@ -131,18 +131,20 @@ let resource_typing_enabled = ref true (* TODO Yanni : reevaluate *) (** [check_validity]: perform validation of transformations *) -let check_validity = ref false +(* let check_validity = ref false *) (* TODO Yanni : reevaluate *) (** [preserve_specs_only]: allow code transformation that preserve the specification without necessarily preserving the semantics TODO: update code which was also using check_validity for this purpose *) -let preserve_specs_only = ref false +(* Deprecated *) +(* let preserve_specs_only = ref false *) (* TODO Yanni : reevaluate *) (** [disable_resource_typing ()] should be called when using OptiTrust without resources. *) -let disable_resource_typing () = +(* Deprecated *) +(* let disable_resource_typing () = resource_typing_enabled := false; - check_validity := false + check_validity := false *) (** [reparse_between_step]: always reparse between two steps *) let reparse_between_steps = ref false @@ -162,8 +164,32 @@ let clang_use_libstdcxx = ref false let aux_file_compare = ref (fun (f1: string) (f2: string) -> true) -(** Possible [execution_mode] of the script *) +(* Start of new flags *) + +type typechecking_mode = + | Unverified (* equivalent to `resource_typing_enabled = false && check_validity = false` *) + | Annotated (* equivalent to `check_validity = false` *) + | AnnotatedAndVerified (* equivalent to `check_validity := true && preserve_specs_only = false` *) + +(** [typechecking_mode]: Defines the verification guarantee of the input code for transformations and typechecking. *) +let typechecking_mode : typechecking_mode ref = ref Annotated (* Should later on be changed to AnnotatedAndVerified *) + +let unverified () : bool = !typechecking_mode = Unverified +let annotated () : bool = (!typechecking_mode = Annotated) || (!typechecking_mode = AnnotatedAndVerified) +let only_annotated () : bool = (!typechecking_mode = Annotated) +let annotated_and_verified () : bool = !typechecking_mode = AnnotatedAndVerified +(* Expected to be a temporary function, to be used in [trace.ml] where there is a [flag_check_validity] flag *) +let match_typechecking_mode (flag_check_validity : bool) = if flag_check_validity then AnnotatedAndVerified else Unverified + +let typechecking_mode_to_string = function + | Unverified -> "Unverivied" + | Annotated -> "Annotated" + | AnnotatedAndVerified -> "AnnotatedAndVerified" + +(* End of new flags *) + +(** Possible [execution_mode] of the script *) type execution_mode = | Execution_mode_step_diff (* produce a diff for a small-step, assumes [target_line] is provided *) | Execution_mode_step_trace (* produce a trace for a small-step, assumes [target_line] is provided *) @@ -403,8 +429,8 @@ let reset_flags_to_default () : unit = display_includes := false; stop_on_first_resource_error := true; resource_typing_enabled := true; - check_validity := false; - preserve_specs_only := false; + (* TO be modified when the code is clean: *) + typechecking_mode := Annotated; reparse_between_steps := false; recompute_resources_between_steps := false; save_steps := None; diff --git a/lib/framework/resources.ml b/lib/framework/resources.ml index bac12427d..565645ea4 100644 --- a/lib/framework/resources.ml +++ b/lib/framework/resources.ml @@ -8,14 +8,16 @@ let ensure_computed = Trace.recompute_resources (* TODO: avoid recomputing all resources for validity checks. TODO: required_for_check_at path; for on-demand computation. *) let required_for_check () : unit = - if !Flags.check_validity && not !Flags.preserve_specs_only - then ensure_computed () + (* Yanni : should require the AnnotatedAndVerified typechecking mode *) + (* if !Flags.check_validity && not !Flags.preserve_specs_only + then *) + ensure_computed () let justif_correct (why : string) : unit = - if !Flags.check_validity then begin - ensure_computed (); - Trace.justif (sprintf "resources are correct: %s" why) - end + (* if !Flags.check_validity then begin *) + ensure_computed (); + Trace.justif (sprintf "resources are correct: %s" why) + (** Returns the resource usage of the given term, fails if unavailable. *) @@ -113,6 +115,7 @@ let fun_minimize_on (t: trm): trm = let new_contract = minimize_fun_contract contract post_inst body_usage in trm_like ~old:t (trm_let_fun name typ args body ~contract:(FunSpecContract new_contract)) +(* TODO : depreciate transformation *) (** [fun_minimize]: minimize a function contract by looking at the resource usage of its body *) let%transfo fun_minimize (tg: target) : unit = ensure_computed (); @@ -334,6 +337,7 @@ let%transfo loop_minimize (*?(indepth : bool = false)*) (tg: target) : unit = Target.apply_at_target_paths loop_minimize_on tg; justif_correct "only changed loop contracts" +(* TODO : depreciate transformation *) let%transfo fix_types_in_contracts (_u: unit): unit = Trace.recompute_resources ~missing_types:true (); let rec add_missing_types (t: trm) = @@ -455,6 +459,7 @@ let set_fun_contract_on (contract: fun_contract) (t: trm): trm = let name, ret_typ, args, body, _ = trm_inv ~error:"Resources.set_fun_contract_on: Expected function" trm_let_fun_inv t in trm_like ~old:t (trm_let_fun name ret_typ args ~contract:(FunSpecContract contract) body) +(* TODO : depreciate transformation *) let%transfo set_fun_contract (contract: unparsed_fun_contract) (tg : Target.target) : unit = Target.apply_at_target_paths (set_fun_contract_on (parse_fun_contract contract)) tg @@ -462,6 +467,7 @@ let set_loop_contract_on (contract: loop_contract) (t: trm): trm = let range, mode, body, _ = trm_inv ~error:"Resource.set_loop_contract_on: Expected for loop" trm_for_inv t in trm_like ~old:t (trm_for ~contract ~mode range body) +(* TODO : depreciate transformation *) let%transfo set_loop_contract ?(strict:bool=true) (contract: unparsed_loop_contract) (tg: Target.target): unit = Target.apply_at_target_paths (set_loop_contract_on (parse_loop_contract ~strict contract)) tg; if not strict then begin diff --git a/lib/framework/runtime/run.ml b/lib/framework/runtime/run.ml index e0f558f74..8cf1498d4 100644 --- a/lib/framework/runtime/run.ml +++ b/lib/framework/runtime/run.ml @@ -150,7 +150,7 @@ let script ?(filename : string option) ~(extension : string) ?(check_exit_at_end let trace_filename = prefix ^ "_trace.js" in if Sys.file_exists trace_filename then Sys.remove trace_filename; Trace.init ~program:program_basename ~prefix filename; - if !Flags.check_validity || !Flags.recompute_resources_between_steps then + if Flags.annotated_and_verified () then Trace.step ~kind:Step_small ~tags:["pre-post-processing"] ~name:"Preprocessing contracts" (fun () -> Resources.fix_types_in_contracts (); Resources.make_strict_loop_contracts []; diff --git a/lib/framework/runtime/trace.ml b/lib/framework/runtime/trace.ml index 7d69ae7f6..791c49f08 100644 --- a/lib/framework/runtime/trace.ml +++ b/lib/framework/runtime/trace.ml @@ -318,7 +318,9 @@ type step_infos = { mutable step_exectime : float; (* seconds *) mutable step_name : string; mutable step_args : (string * string) list; - mutable step_flag_check_validity : bool; (* state of flag check_validity at start; must be the same at end *) + (* Yanni : Deprecated flag *) + mutable step_typechecking_mode : Flags.typechecking_mode; + (* mutable step_flag_check_validity : bool; (* state of flag check_validity at start; must be the same at end *) *) mutable step_valid : bool; mutable step_justif : string list; (* accumulated in reverse order during the step *) mutable step_tags : string list; (* accumulated in reverse order during the step *) @@ -722,7 +724,8 @@ let open_root_step ?(source : string = "") () : unit = step_name = ""; step_args = [("extension", the_trace.cur_context.extension) ]; step_justif = []; - step_flag_check_validity = !Flags.check_validity && (not !Flags.use_resources_with_models); + step_typechecking_mode = !Flags.typechecking_mode; + (* step_flag_check_validity = !Flags.check_validity && (not !Flags.use_resources_with_models); *) step_valid = false; step_tags = []; step_debug_msgs = []; @@ -770,7 +773,8 @@ let open_step ?(valid:bool=false) ?(line : int option) ?(step_script:string="") step_name = name; step_args = []; step_justif = []; - step_flag_check_validity = !Flags.check_validity && (not !Flags.use_resources_with_models); + step_typechecking_mode = !Flags.typechecking_mode; + (* step_flag_check_validity = !Flags.check_validity && (not !Flags.use_resources_with_models); *) step_valid = valid; step_tags = tags; step_debug_msgs = []; @@ -794,7 +798,7 @@ let open_step ?(valid:bool=false) ?(line : int option) ?(step_script:string="") step (** [change_step] helps creating a [Step_change] during [finalize]. *) -let change_step ~(ast_before:trm) ~(style:output_style) ~(ast_after:trm) ~(time_start : float) ~(step_exectime : float) ~(flag_check_validity:bool) : step_tree = +let change_step ~(ast_before:trm) ~(style:output_style) ~(ast_after:trm) ~(time_start : float) ~(step_exectime : float) ~(typechecking_mode:Flags.typechecking_mode) : step_tree = let infos = { step_id = next_step_id(); step_script = ""; @@ -804,7 +808,8 @@ let change_step ~(ast_before:trm) ~(style:output_style) ~(ast_after:trm) ~(time_ step_name = "Changed AST directly"; step_args = []; step_justif = []; - step_flag_check_validity = flag_check_validity; + step_typechecking_mode = typechecking_mode; + (* step_flag_check_validity = flag_check_validity; *) step_valid = false; step_tags = []; step_debug_msgs = []; @@ -876,11 +881,12 @@ let tag_simpl_access () : unit = tag "simpl"; tag "simpl_access" +(* Yanni : might change this flag to [Flags.Annotated] instead *) (** [without_substep_validity_checks f] executes [f] with the flag [check_validity] temporarily set to false. Only for internal use; user scripts should use the [trustme] function. *) let without_substep_validity_checks (f: unit -> 'a): 'a = - Flags.with_flag Flags.check_validity false f + Flags.with_flag (* Flags.check_validity false *) Flags.typechecking_mode Flags.Unverified f (** [make_substeps_chained step] Finalize the list of substeps of [step], by inserting [Step_change] steps where the ast was modified directly @@ -888,7 +894,8 @@ let without_substep_validity_checks (f: unit -> 'a): 'a = by applying the series of substep, each substep starting from the same physical ast as the one produced by the previous step. *) let make_substeps_chained (step:step_tree) : unit = - let flag_check_validity = step.step_infos.step_flag_check_validity in + (* let flag_check_validity = step.step_infos.step_flag_check_validity in *) + let typechecking_mode = step.step_infos.step_typechecking_mode in let style = step.step_style_before in let before (s:step_tree) : trm = s.step_ast_before in @@ -905,7 +912,7 @@ let make_substeps_chained (step:step_tree) : unit = if before substep != !cur_ast then begin let changestep = change_step ~ast_before:(!cur_ast) ~ast_after:(before substep) ~time_start:(!cur_time) ~step_exectime:(time_start substep -. !cur_time) - ~flag_check_validity ~style in + ~typechecking_mode ~style in (* or style:(Style.default_custom_style()) *) Tools.ref_list_add newsubrev changestep; end; @@ -920,7 +927,7 @@ let make_substeps_chained (step:step_tree) : unit = if step.step_sub <> [] && !cur_ast != step.step_ast_after then begin let changestep = change_step ~ast_before:(!cur_ast) ~ast_after:step.step_ast_after ~time_start:(!cur_time) ~step_exectime:(time_stop step -. !cur_time) - ~flag_check_validity ~style in + ~typechecking_mode ~style in Tools.ref_list_add newsubrev changestep; end; step.step_sub <- List.rev !newsubrev @@ -974,13 +981,13 @@ let rec finalize_step ~(on_error: bool) (step : step_tree) : unit = if not (is_kind_preserving_code step.step_kind) then make_substeps_chained step; (* Check that [Flags.check_validity] is like at the start of the step *) - if not on_error && (!Flags.check_validity && (not !Flags.use_resources_with_models)) <> infos.step_flag_check_validity + if not on_error && (!Flags.typechecking_mode <> infos.step_typechecking_mode) (* (!Flags.check_validity && (not !Flags.use_resources_with_models)) <> infos.step_flag_check_validity *) then raise (TraceFailure "At finalize_step, Flags.check_validity is not same as when step was opened."); (* Set the validity flag if it is not already set, in particular if the step is an identity step, or if all substeps are valid. (they have previously been ensured to form a chain). A [Step_trustme] is always considered invalid. *) - if !Flags.check_validity then begin + if (* !Flags.check_validity *) Flags.annotated () then begin if step.step_kind = Step_trustme then step.step_infos.step_valid <- false else if not infos.step_valid @@ -1643,7 +1650,8 @@ let rec dump_step_tree_to_js ~(is_substep_of_targeted_line:bool) (root_id:int)(o "script_line", Json.(optionof int) (if i.step_script_line = Some (-1) then None else i.step_script_line); (* TODO: avoid use of -1 for undef line *) "args", Json.(listof (fun (k,v) -> Json.obj_quoted_keys ["name", str k; "value",str v])) i.step_args; - "check_validity", Json.bool i.step_flag_check_validity; + (* "check_validity", Json.bool i.step_flag_check_validity; *) + "typechecking_mode", Json.str (Flags.typechecking_mode_to_string i.step_typechecking_mode); "isvalid", Json.bool i.step_valid; (* TODO: at the moment, we assume that a justification item means is-valid *) "justif", Json.(listof str) i.step_justif; diff --git a/lib/transfo/accesses_basic.ml b/lib/transfo/accesses_basic.ml index ad31bedcd..2ff1fcde2 100644 --- a/lib/transfo/accesses_basic.ml +++ b/lib/transfo/accesses_basic.ml @@ -212,13 +212,13 @@ let%transfo transform (f_get : trm -> trm) (f_set : trm -> trm) Marks.with_marks (fun next_mark -> Target.iter (fun p -> let (p_seq, span) = Path.extract_last_dir_span p in let (mark_to_prove, mark_preprocess, mark_postprocess, mark_handled_resources) = - if !Flags.check_validity && not !Flags.preserve_specs_only then begin + if (* !Flags.check_validity && not !Flags.preserve_specs_only *) Flags.annotated_and_verified () then begin (Mark.reuse_or_next next_mark mark_to_prove, Mark.reuse_or_next next_mark mark_preprocess, Mark.reuse_or_next next_mark mark_postprocess, next_mark ()) end else - (mark_to_prove, mark_preprocess, mark_postprocess, no_mark) + (mark_to_prove, mark_preprocess, mark_postprocess, no_mark) in let ret = { typedvar = ref None; @@ -230,7 +230,7 @@ let%transfo transform (f_get : trm -> trm) (f_set : trm -> trm) pure_post = ref []; } in Target.apply_at_path (transform_on f_get f_set f_cancel to_prove address_pattern mark_to_prove mark_preprocess mark_postprocess mark_handled_resources ret span) p_seq; - if !Flags.check_validity && not !Flags.preserve_specs_only then begin + if (* !Flags.check_validity && not !Flags.preserve_specs_only *) Flags.annotated_and_verified () then begin (* TODO: factorize with local_name, should this be a Resource.assert_??? feature? may also be decomposed via elim_reuse? *) let error = "did not find on which inner pointer variable addresses where based" in let (v, ty_opt) = Option.unsome ~error !(ret.typedvar) in @@ -339,9 +339,9 @@ let%transfo transform_arith ~(op:transform_arith_op) ?(inv:bool=false) ~(factor: ?(mark_preprocess : mark = no_mark) ?(mark_postprocess : mark = no_mark) (tg : target) : unit = Nobrace_transfo.remove_after (fun () -> - if !Flags.check_validity && not !Flags.preserve_specs_only then + (* if !Flags.check_validity && not !Flags.preserve_specs_only then if not (Resources.trm_is_pure factor) then - trm_fail factor "basic variable scaling does not support non-pure arguments"; + trm_fail factor "basic variable scaling does not support non-pure arguments"; *) let () = match op with | Transform_arith_add -> Trace.justif "factor is pure"; @@ -366,9 +366,9 @@ let%transfo transform_arith ~(op:transform_arith_op) ?(inv:bool=false) ~(factor: ) let%transfo transform_arith_immut ~(op:transform_arith_op) ?(inv : bool = false) ~(factor : trm) ?(mark : mark = no_mark) (tg : target) : unit = - if !Flags.check_validity && not !Flags.preserve_specs_only then + (* if !Flags.check_validity && not !Flags.preserve_specs_only then if not (Resources.trm_is_pure factor) then - trm_fail factor "basic variable scaling does not support non-pure arguments"; + trm_fail factor "basic variable scaling does not support non-pure arguments"; *) Trace.justif "factor is pure and will be proved != 0"; let typ = Option.unsome ~error:"Arith.scale: factor needs to have a known type" factor.typ in let op_get, op_set = diff --git a/lib/transfo/arith_basic.ml b/lib/transfo/arith_basic.ml index 0ec5efa83..b0320d687 100644 --- a/lib/transfo/arith_basic.ml +++ b/lib/transfo/arith_basic.ml @@ -41,7 +41,8 @@ let%transfo simpl ?(indepth : bool = false) (f: (expr -> expr)) (tg : target) : Trace.without_resource_computation_between_steps (fun () -> Target.apply_at_target_paths (fun t -> let f_postprocess (t: trm) (simpl_t: trm): trm = - if not !Flags.check_validity then begin + (* Yanni : This is a case where we should not delete the effect, since arithmetic simplifications should be different depending on the annotation flag. *) + if not (* !Flags.check_validity *) (Flags.annotated_and_verified ()) then begin simpl_t end else begin let open Resource_formula in @@ -135,11 +136,13 @@ let%transfo simplify ?(indepth : bool = false) (tg : target) : unit = let constr = cPrimPredCall is_prim_arith +(* TODO : depreciate transformation *) (** [clear_nosimpl tg]: clears all the marks on all the instructions that where skipped by the simplifier *) let%transfo clear_nosimpl (tg : target) : unit = Marks.remove Arith_core.mark_nosimpl [nbMulti; cMark Arith_core.mark_nosimpl] +(* TODO : depreciate transformation *) (** [nosimplf tg]: mark all the instructions targeted by [tg] as "__arith_core_nosimpl" *) let%transfo nosimpl (tg : target) : unit = Marks.add Arith_core.mark_nosimpl tg diff --git a/lib/transfo/arith_core.ml b/lib/transfo/arith_core.ml index b3f973623..2cecf4d05 100644 --- a/lib/transfo/arith_core.ml +++ b/lib/transfo/arith_core.ml @@ -615,12 +615,14 @@ let get_purity (t : trm) : purity = deletable = true } end else begin let noinfo () = { redundant = false; deletable = false } in - if not !Flags.check_validity then begin + if not (* !Flags.check_validity *) (Flags.annotated_and_verified ()) then begin (* Second, if resources are never computed, don't try to read resources *) noinfo() end else begin try (* Else, try resource-based criteria *) + (* LATER Yanni : Resource functions should be the one looking up the flags : + The resource computation functions will compute the asked property iff the annotations are considered verified `Flags.annotated_and_verified ()` *) let redundant = Resources.is_not_self_interfering t in let deletable = Resources.is_deletable t in { redundant; deletable } diff --git a/lib/transfo/arrays.ml b/lib/transfo/arrays.ml index 785ae84d9..9fa6037fe 100644 --- a/lib/transfo/arrays.ml +++ b/lib/transfo/arrays.ml @@ -45,6 +45,7 @@ let unroll_index_vars_from_array_reads (tg : target) : unit = (* FIXME: should be equal to arith default? *) let default_inline_constant_simpl tg = Arith.(simpl_surrounding_expr (fun x -> compute (gather x))) (nbAny :: tg) +(* TODO : depreciate transformation *) (** [inline_constant] expects the target [decl] to point at a constant array literal declaration, and resolves all accesses targeted by [tg], that must be at constant indices. For every variable in non-constant indices, this transformation will attempt unrolling the corresponding for loop. *) @@ -58,6 +59,7 @@ let%transfo inline_constant ?(mark_accesses : mark = no_mark) ~(decl : target) ? Arrays_basic.inline_constant ~mark_accesses ~decl [nbMulti; cMark m] ) +(* TODO : depreciate transformation *) (** [elim_constant] expects the target [tg] to point at a constant array literal declaration, and resolves all its accesses, that must be at constant indices. Then, eliminates the array declaration. *) let%transfo elim_constant ?(mark_accesses : mark = no_mark) (tg : target) : unit = diff --git a/lib/transfo/arrays_basic.ml b/lib/transfo/arrays_basic.ml index 4ad4c30bc..e10f155ec 100644 --- a/lib/transfo/arrays_basic.ml +++ b/lib/transfo/arrays_basic.ml @@ -1,6 +1,7 @@ open Prelude open Target +(* TODO : depreciate transformation *) (** [to_variables new_vars tg]: expects the target [tg] to point at an array declaration. Then it transforms this declaration into a list of declarations. [new_vars] - denotes the list of variables that is going to replace the initial declaration @@ -11,6 +12,7 @@ let%transfo to_variables (new_vars : string list) (tg : target) : unit = ) +(* TODO : depreciate transformation *) (** [tile ~block_type block_size tg]: expects the target [tg] to point at an array declaration. Then it takes that declaration and transforms it into a tiled array. All the accesses of the targeted array are handled as well. @@ -21,6 +23,7 @@ let%transfo tile ?(block_type : string = "") (block_size : var) (tg : target) : apply_at_target_paths_in_seq (Arrays_core.tile_at block_type block_size) tg ) +(* TODO : depreciate transformation *) (** [swap name x tg]: expects the target [tg] to point at an array declaration. It changes the declaration so that the bounds of the array are switched. Also all the accesses of the targeted array are handled as well.*) @@ -61,6 +64,7 @@ let aos_to_soa (tv : typvar) (sz : var) : unit = Arrays_core.aos_to_soa_rec tv sz t ) +(* TODO : depreciate transformation *) (** [set_explicit tg] expects the target [tg] to point at an array declaration then it will remove the initialization trm and a list of write operations on each of the cells of the targeted array. @@ -83,6 +87,7 @@ let inline_constant_on (array_var : var) (array_vals : trm list) (mark_accesses | _ -> trm_fail index error end +(* TODO : depreciate transformation *) (** [inline_constant] expects the target [decl] to point at a constant array literal declaration, and resolves all accesses targeted by [tg], that must be at constant indices. *) let%transfo inline_constant ?(mark_accesses : mark = no_mark) ~(decl : target) (tg : target) : unit = @@ -110,6 +115,7 @@ let elim_on (decl_index : int) (t : trm) : trm = let new_instrs = Mlist.update_nth decl_index remove_decl instrs in trm_seq ~annot:t.annot ?loc:t.loc ?result new_instrs +(* TODO : depreciate transformation *) (** [elim] expects the target [tg] to point at a constant array literal declaration, and eliminates it if it is not accessed anymore. *) let%transfo elim (tg : target) : unit = diff --git a/lib/transfo/function.ml b/lib/transfo/function.ml index 6af42f497..5f1715cc2 100644 --- a/lib/transfo/function.ml +++ b/lib/transfo/function.ml @@ -93,7 +93,7 @@ let%transfo inline ?(resname : string = "") Marks.add call_mark (target_of_path p); let new_target = cMark call_mark in - let inline_mark = if !Flags.check_validity then next_mark () else no_mark in + let inline_mark = (* if !Flags.check_validity then next_mark () else *) no_mark in bind_args ~inline_impure_mark:inline_mark args [new_target]; let body_mark = "__TEMP_BODY" ^ (string_of_int i) in diff --git a/lib/transfo/function_basic.ml b/lib/transfo/function_basic.ml index ed9264b12..61a2bb6fa 100644 --- a/lib/transfo/function_basic.ml +++ b/lib/transfo/function_basic.ml @@ -9,7 +9,7 @@ open Target let%transfo delete (tg : target) : unit = let tr () = Sequence_basic.delete tg in - if !Flags.check_validity then begin + if (* !Flags.check_validity *) Flags.annotated_and_verified () then begin Target.iter (fun p -> let error = "Function.delete expects to target a function definition within a sequence" in let (_, _, _, _, _) = trm_inv ~error trm_let_fun_inv (resolve_path p) in diff --git a/lib/transfo/function_core.ml b/lib/transfo/function_core.ml index d5661769f..42c2a977f 100644 --- a/lib/transfo/function_core.ml +++ b/lib/transfo/function_core.ml @@ -75,13 +75,13 @@ let beta_reduce_on ?(body_mark : mark = no_mark) ?(subst_mark : mark = no_mark) in let subst_map = List.fold_left2 (fun subst_map dv cv -> Var_map.add dv (trm_add_mark subst_mark cv) subst_map) subst_map fun_decl_arg_vars fun_call_args in - if !Flags.check_validity then begin + (* if !Flags.check_validity then begin Var_map.iter (fun _ arg_val -> if not (Resources.trm_is_pure arg_val) then trm_fail arg_val "basic function inlining does not support non-pure arguments, combine with variable binding and inline" ) subst_map; Trace.justif "inlining a function when all arguments are pure is always correct" - end; + end; *) let fun_decl_body = trm_subst subst_map (trm_copy body) in (* LATER: In presence of a goto, this generates an ugly varaible name (res) and label name (exit) while we should be able to handle user given names. *) let processed_body = replace_return_with_assign_goto fun_decl_body in @@ -160,14 +160,14 @@ let use_infix_ops_on (allow_identity : bool) (t : trm) : trm = | Some (ti,_purity) -> if is_get_of_ls ti then begin (* found the [get(ls)], check duplicatability, then remove the item from the list *) - if !Flags.check_validity && not !Flags.preserve_specs_only then begin + (* if !Flags.check_validity && not !Flags.preserve_specs_only then begin if not purity.redundant then fail "Unable to introduce an infix op, because the LHS is not a duplicatable expressions."; Trace.justif "the expression denoting the address is redundant."; wes' - end else begin + end else begin *) wes' (* validity not checked *) - end + (* end *) end else begin (* else search further *) we::(remove_one_get_ls wes') @@ -275,11 +275,11 @@ let uninline_on (fct_decl : trm) let ret_args = Trm.tmap_to_list (List.map fst ret_targs) inst in (* 4. check validity: instantiated arguments must be pure, and a separate resource must be owned on the eventual return variable *) - if !Flags.check_validity then begin + (* if !Flags.check_validity then begin Var_map.iter (fun _ arg_val -> if not (Resources.trm_is_pure arg_val) then trm_fail arg_val "basic function uninlining does not support non-pure arguments, combine with variable binding and inline" - ) inst; + ) inst; *) (* DEPRECATED: is it really dangerous to alias an argument resource with the return address resource? match !ret_var with | None -> () diff --git a/lib/transfo/ghost_pair.ml b/lib/transfo/ghost_pair.ml index 7a829c3ac..6b95b8fa8 100644 --- a/lib/transfo/ghost_pair.ml +++ b/lib/transfo/ghost_pair.ml @@ -230,6 +230,7 @@ let intro_at ?(name: string option) ?(end_mark: mark = no_mark) (i: int) (t_seq: let seq = Mlist.merge_list [seq_before; Mlist.of_list [ghost_begin]; seq_after] in trm_replace (Trm_seq (seq, result)) t_seq +(* TODO : depreciate transformation *) (** Introduce a ghost pair starting on the targeted ghost, and ending at the first closing candidate. *) let%transfo intro ?(name: string option) ?(end_mark: mark = no_mark) (tg: target) = Resources.ensure_computed (); @@ -261,6 +262,7 @@ let elim_at ?(mark_begin: mark = no_mark) ?(mark_end: mark = no_mark) (i: int) ( let seq = Mlist.merge_list [seq_before; Mlist.of_list [trm_add_mark mark_begin (Resource_trm.ghost { ghost_fn = without_inverse ghost_fn; ghost_args; ghost_bind })]; seq_after] in trm_replace (Trm_seq (seq, result)) t_seq +(* TODO : depreciate transformation *) (** Split a ghost pair into two independant ghost calls *) let%transfo elim ?(mark_begin: mark = no_mark) ?(mark_end: mark = no_mark) (tg: target) = Resources.ensure_computed (); @@ -344,6 +346,7 @@ let move_in_loop_on (i : int) (t : trm) : trm = trm_seq_helper [ TrmMlist (Mlist.pop_back lbefore); Trm (trm_for ~mode ~contract:new_contract range new_body); TrmMlist (Mlist.pop_front lafter) ] +(* TODO : depreciate transformation *) (** [move_in_loop tg]: Expects the target to point at a loop Will try to ove the first ghost pairs inside the loop body : Transform : diff --git a/lib/transfo/ghost_pure.ml b/lib/transfo/ghost_pure.ml index bbc734eaf..a0f2c4565 100644 --- a/lib/transfo/ghost_pure.ml +++ b/lib/transfo/ghost_pure.ml @@ -212,6 +212,7 @@ let copy_inside_from_seq (index: int) (seq: trm): trm = trm_like ~old:seq (trm_seq_helper ?result [TrmMlist tl_before; Trm new_t; TrmMlist tl_after]) +(* TODO : depreciate transformation *) (** Copies all the pure ghosts of the surrounding sequence at the begining of the body of the targetted instruction. *) let%transfo copy_surrounding_inside (tg: target): unit = Target.apply_at_target_paths_in_seq copy_inside_from_seq tg; diff --git a/lib/transfo/gpu.ml b/lib/transfo/gpu.ml index 192de5803..4aed5a7f8 100644 --- a/lib/transfo/gpu.ml +++ b/lib/transfo/gpu.ml @@ -11,7 +11,7 @@ include Gpu_basic It is always assumed that the leaf will be converted. *) let%transfo convert_tail_thread_for (loops : int list) (leaf: target) = let fission_helper tg = - Flags.with_flag Flags.check_validity true (fun () -> Loop.fission tg) in + Flags.with_flag (* Flags.check_validity true *) Flags.typechecking_mode Flags.AnnotatedAndVerified (fun () -> Loop.fission tg) in let rec aux barrier_mark loops_incl_leaf leaf_p: unit = let convert,loops = match loops_incl_leaf with | 0 :: tl -> false, tl diff --git a/lib/transfo/gpu_basic.ml b/lib/transfo/gpu_basic.ml index 1530fff6b..02e041f53 100644 --- a/lib/transfo/gpu_basic.ml +++ b/lib/transfo/gpu_basic.ml @@ -452,6 +452,7 @@ let remove_loop_around_barrier (tg: target): unit = ()) tg +(* TODO : depreciate transformation *) let%transfo insert_barrier (tg: target) = Sequence_basic.insert ~reparse:false (magic_barrier ()) tg diff --git a/lib/transfo/if_basic.ml b/lib/transfo/if_basic.ml index 2c901241d..83c294594 100644 --- a/lib/transfo/if_basic.ml +++ b/lib/transfo/if_basic.ml @@ -19,14 +19,14 @@ let insert_on (cond : trm) (mark : mark) (mark_then : mark) (mark_else : mark) ( Note: If [cond] is given as arbitrary string the flag [reparse] should be set to true. *) let%transfo insert ?(cond : trm = trm_any_bool) ?(reparse : bool = false) ?(mark : mark = no_mark) ?(mark_then : mark = no_mark) ?(mark_else : mark = no_mark) ?(else_branch : bool = true) (tg : target) : unit = - if !Flags.check_validity then begin + (* if !Flags.check_validity then begin if else_branch = false then failwith "inserting if without else requires further checks"; if Resources.trm_is_pure cond then Trace.justif "pure condition can safely be inserted" else (* TODO: check that Insert.instr cond is OK. *) trm_fail cond "condition is not pure, more advanced checks not yet supported" - end; + end; *) Target.reparse_after ~reparse (Target.apply_at_target_paths (insert_on cond mark mark_then mark_else else_branch)) tg let elim_true_on (t : trm) : trm = @@ -34,6 +34,7 @@ let elim_true_on (t : trm) : trm = let (_cond, th, _el) = trm_inv ~error trm_if_inv t in th +(* TODO : depreciate transformation *) (* hypothesis: if condition evaluates to `true` *) let%transfo elim_true (tg : target) : unit = apply_at_target_paths elim_true_on tg @@ -43,6 +44,7 @@ let elim_false_on (t : trm) : trm = let (_cond, _th, el) = trm_inv ~error trm_if_inv t in el +(* TODO : depreciate transformation *) (* hypothesis: if condition evaluates to `false` *) let%transfo elim_false (tg : target) : unit = apply_at_target_paths elim_false_on tg diff --git a/lib/transfo/instr.ml b/lib/transfo/instr.ml index f5ad57a88..61c826c13 100644 --- a/lib/transfo/instr.ml +++ b/lib/transfo/instr.ml @@ -264,7 +264,7 @@ let%transfo gather_targets ?(dest : gather_dest = GatherAtLast) (tg : target) : *) let%transfo move ~(dest : target) (tg : target) : unit = Trace.tag_atomic (); - if !Flags.check_validity then + (* if !Flags.check_validity then (* TODO: handle move out of loop, conditions, etc. *) Target.iter (fun p -> let seq_path, span = Path.extract_last_dir_span p in @@ -273,7 +273,8 @@ let%transfo move ~(dest : target) (tg : target) : unit = path_fail dest_path "Instr.move: Unsupported move outside the sequence when checking validity"; move_in_seq ~dest:[dBefore i] (target_of_path p) ) tg - else begin + else *) + begin Target.iter (fun p -> let tg_trm = Target.resolve_path p in Marks.add "instr_move_out" (target_of_path p); diff --git a/lib/transfo/instr_basic.ml b/lib/transfo/instr_basic.ml index 244314176..d3c37d380 100644 --- a/lib/transfo/instr_basic.ml +++ b/lib/transfo/instr_basic.ml @@ -62,7 +62,8 @@ let%transfo move ?(mark_moved : mark = no_mark) let seq, swapped_after = Mlist.split mid_index seq in let untouched_before, swapped_before = Mlist.split ~left_bias:true before_index seq in - if !Flags.check_validity && not !Flags.use_resources_with_models then begin + (* Yanni : Deprecated condition - We always use resources with models now *) + (* if !Flags.check_validity && not !Flags.use_resources_with_models then begin let usage_before = Resources.compute_usage_of_instrs swapped_before in let usage_after = Resources.compute_usage_of_instrs swapped_after in let ctx = [ @@ -71,7 +72,7 @@ let%transfo move ?(mark_moved : mark = no_mark) ] in Resources.assert_usages_commute ctx usage_before usage_after; Trace.justif "resources commute" - end; + end; *) let (moved_beg, moved_end) = span_marks mark_moved in trm_seq_helper ~annot:t_seq.annot ?result ( diff --git a/lib/transfo/label_basic.ml b/lib/transfo/label_basic.ml index 390094df5..5cf742765 100644 --- a/lib/transfo/label_basic.ml +++ b/lib/transfo/label_basic.ml @@ -12,6 +12,7 @@ open Target - label as a standalone instruction (=> currently encoded as Trm_label ("foo", trm_unit)) - or label around an instruction. *) +(* TODO : depreciate transformation *) (** [add label tg]: adds a C-label named [label] to the front of the terms matching the target [tg]. Does nothing if [label = no_label]. diff --git a/lib/transfo/loop.ml b/lib/transfo/loop.ml index 9c00c1c5a..cabab6904 100644 --- a/lib/transfo/loop.ml +++ b/lib/transfo/loop.ml @@ -38,7 +38,7 @@ let rec fission_rec (next_mark : unit -> mark) (nest_of : int) (m_interstice : m else if i = Mlist.length loop_body_instrs then Marks.add m_between [cPath p_loop; tAfter] else begin - let m_interstice = if !Flags.check_validity then begin (* FIXME: hide condition between better API? *) + let m_interstice = if (* !Flags.check_validity *) Flags.annotated () then begin (* FIXME: hide condition between better API? *) let m = next_mark () in Ghost_pair.fission ~mark_between:m (target_of_path p_interstice); Ghost_pure.fission ~mark_clears:m_clears [cPath p_loop_body; cMark m]; @@ -53,7 +53,7 @@ let rec fission_rec (next_mark : unit -> mark) (nest_of : int) (m_interstice : m (* TODO: this is required if other transformations like Variable_basic.inline don't eagerly do it. *) Resources.make_strict_loop_contracts [cPath p_loop]; fission_basic ~mark_loops:m_loops ~mark_between_loops:m_between [cPath p_loop_body; cMark m_interstice]; - if !Flags.check_validity then begin (* FIXME: hide condition between better API? *) + if (* !Flags.check_validity *) Flags.annotated () then begin (* FIXME: hide condition between better API? *) Ghost_pair.minimize_all_in_seq [nbExact 2; cPath p_outer_seq; cMark m_loops; dBody]; Resources.loop_minimize [nbExact 2; cPath p_outer_seq; cMark m_loops]; Ghost_pure.remove_clears m_clears [occFirst; cPath p_outer_seq; cMark m_loops; dBody]; @@ -104,7 +104,7 @@ let%transfo move_out_bis Resources.make_strict_loop_contracts []; let loop_mark = next_mark () in Loop_basic.move_out ~loop_mark [cPath seq_path; Constr_depth (DepthAt 0); tSpan [tFirst] [cMarkSpanStop mark_moved]]; - if !Flags.check_validity then Resources.loop_minimize [cMark loop_mark]; + if (* !Flags.check_validity *) Flags.annotated () then Resources.loop_minimize [cMark loop_mark]; ) tg) (* TODO: redundant with 'hoist' *) @@ -420,7 +420,7 @@ let%transfo simpl_scoped_ghosts (ghosts_before : trm list) (ghosts_after : trm l #equiv-rewrite: fixes a similar problem as the code in Variable_basic.subst . *) let%transfo simpl_scoped ~(simpl : unit -> unit) (tg : target) : unit = - if !Flags.check_validity then Target.iter (fun p -> + if (* !Flags.check_validity *) Flags.annotated () then Target.iter (fun p -> Nobrace_transfo.remove_after (fun () -> Trace.without_resource_computation_between_steps (fun () -> let error = "expected for loop" in @@ -782,7 +782,7 @@ let%transfo move_out ?(upto : string = "") (tg : target) : unit = Instr_basic.move ~dest:[tFirst] (target_of_path instr_p); let loop_m = next_mark () in Loop_basic.move_out ~loop_mark:loop_m instr_tg; - if !Flags.check_validity then + if (* !Flags.check_validity *) Flags.annotated () then Resources.loop_minimize [cMark loop_m]; in Target.iter (fun instr_p -> Marks.with_marks (fun next_mark -> diff --git a/lib/transfo/loop_basic.ml b/lib/transfo/loop_basic.ml index 918150c26..62e71005a 100644 --- a/lib/transfo/loop_basic.ml +++ b/lib/transfo/loop_basic.ml @@ -3,6 +3,7 @@ open Target open Matrix_trm open Loop_core +(* TODO : depreciate transformation *) (** [color nb_colors i_color tg]: expects the target [tg] to point at a simple for loop, let's say [for (int i = start; i < stop; i += step) { body } ]. [nb_colors] - an expression denoting the number of colors (e.g., ["2"]), @@ -95,7 +96,8 @@ let collapse_on (simpl_mark : mark) (index : string) let ghosts_before = add_collapse_ghost ghost_group_collapse ghost_ro_group_collapse cj.iter_contract.pre.linear in let ghosts_after = add_collapse_ghost ghost_group_uncollapse ghost_ro_group_uncollapse cj.iter_contract.post.linear in let contract = Resource_contract.loop_contract_subst subst cj in - let body2 = if !Flags.check_validity then + let body2 = body + (* if !Flags.check_validity then let instrs, _ = trm_inv ~error:"expected seq" trm_seq_inv body in let open Resource_formula in let open Resource_trm in @@ -104,11 +106,10 @@ let collapse_on (simpl_mark : mark) (index : string) Mlist.push_front (assume (formula_in_range new_i (formula_loop_range ri))) in trm_seq ~annot:body.annot instrs2 - else - body + else *) in let t2 = trm_for ~contract rk (trm_subst subst body2) in - if !Flags.check_validity then begin + (* if !Flags.check_validity then begin Resource_formula.(Resource_trm.(trm_seq_helper ~braces:false [ Trm (assume (formula_geq ~typ:typ_int ri.stop (trm_int 0))); Trm (assume (formula_geq ~typ:typ_int rj.stop (trm_int 0))); @@ -116,8 +117,8 @@ let collapse_on (simpl_mark : mark) (index : string) Trm t2; TrmList ghosts_after ])) - end else - t2 + end else *) + t2 (** [collapse]: expects the target [tg] to point at a simple loop nest: [for i in 0..Ni { for j in 0..Nj { b(i, j) } }] @@ -142,7 +143,7 @@ let%transfo collapse ?(simpl_mark : mark = no_mark) let ri_rj_body = ref None in let _ = Path.apply_on_path (collapse_analyse ri_rj_body) (Trace.ast ()) p in let (ri, ci, rj, cj, body) = Option.get !ri_rj_body in - if !Flags.check_validity then begin + (* if !Flags.check_validity then begin (* DEPRECATED: using assume instead step_backtrack ~discard_after:true (fun () -> Target.apply_at_path (fun t -> @@ -155,7 +156,7 @@ let%transfo collapse ?(simpl_mark : mark = no_mark) ); *) Trace.justif "correct when start >= stop for both ranges" - end; + end; *) Target.apply_at_path (collapse_on simpl_mark index ri ci rj cj body) p ) tg) @@ -277,9 +278,9 @@ let fission_on_as_pair (mark_loops : mark) (index : int) (t : trm) : trm * trm = let tl, _ = trm_inv trm_seq_inv t_seq in let tl1, _, tl2 = Mlist.split_on_marks index tl in let fst_contract, snd_contract = - if not !Flags.check_validity then + (* if not !Flags.check_validity then empty_loop_contract, empty_loop_contract - else + else *) let open Resource_formula in if not contract.strict then trm_fail t "Loop_basic.fission_on: requires a strict loop contract to check validity"; @@ -569,7 +570,7 @@ let fusion_on (index : int) (upwards : bool) (t : trm) : trm = strict = true; } end - end else if !Flags.check_validity then + end else if (* !Flags.check_validity *) Flags.annotated () then trm_fail t "requires annotated for loops to check validity" else empty_loop_contract @@ -661,7 +662,8 @@ let move_out_on (instr_mark : mark) (loop_mark : mark) (empty_range: empty_range let instrs, _ = trm_inv ~error trm_seq_inv body in let (rest, moved_instrs) = Mlist.extract span.start span.stop instrs in - if !Flags.check_validity && not !Flags.use_resources_with_models then begin + (* Deprecated loop *) + (* if !Flags.check_validity && not !Flags.use_resources_with_models then begin Mlist.iteri (fun i instr -> if is_free_var_in_trm range.index instr then (* NOTE: would be checked by var ids anyway *) @@ -682,7 +684,7 @@ let move_out_on (instr_mark : mark) (loop_mark : mark) (empty_range: empty_range end; Trace.justif "instructions from following iterations are redundant with first iteration" - end; + end; *) let generate_if = (empty_range = Generate_if) in let contract = @@ -758,7 +760,8 @@ let move_out_alloc_on (trm_index : int) (t : trm) : trm = let error = "expected free instr" in let _ = trm_inv ~error Matrix_trm.free_inv free_instr in - if !Flags.check_validity then begin + (* Deprecated loop *) + (* if !Flags.check_validity then begin (* NOTE: would be checked by var ids anyway *) if is_free_var_in_trm range.index alloc_instr then trm_fail alloc_instr "allocation instruction uses loop index"; @@ -769,7 +772,7 @@ let move_out_alloc_on (trm_index : int) (t : trm) : trm = *) Trace.justif "instructions from following iterations are redundant with first iteration" - end; + end; *) let open Resource_formula in let contract = { contract with invariant = { contract.invariant with linear = (new_anon_hyp (), formula_uninit_matrix ~mem_typ:Resource_formula.mem_typ_any (trm_var array_var) dims) :: contract.invariant.linear }} in (* TODO upgrade to multiple mem types (#24) *) @@ -962,7 +965,8 @@ let%transfo shift_range (index : string) (kind : shift_kind) ?(mark_for : mark = no_mark) ?(mark_contract_occs : mark = no_mark) (tg : target) : unit = - if !Flags.check_validity then begin + (* Deprecatred *) + (* if !Flags.check_validity then begin match kind with | ShiftBy v | StartAt v | StopAt v -> if Resources.trm_is_pure v then @@ -971,7 +975,7 @@ let%transfo shift_range (index : string) (kind : shift_kind) else trm_fail v "shifting by a non-pure expression is not yet supported, requires checking that expression is read-only, introduce a binding with 'Sequence.insert' to workaround" (* TODO: combi doing this *) | StartAtZero -> Trace.justif "shifting to zero is always correct, loop range is read-only" - end; + end; *) Nobrace_transfo.remove_after (fun () -> Target.apply_at_target_paths (shift_range_on kind index mark_let mark_for mark_contract_occs) tg) @@ -1038,13 +1042,14 @@ let%transfo scale_range (index : string) (factor : trm) ?(mark_for : mark = no_mark) ?(mark_contract_occs : mark = no_mark) (tg : target) : unit = - if !Flags.check_validity then begin + (* Deprecated *) + (* if !Flags.check_validity then begin if Resources.trm_is_pure factor then (* TODO: also works for read-only *) Trace.justif "scaling by a pure factor is correct when proving that factor != 0" else trm_fail factor "scaling by a non-pure expression is not yet supported, requires checking that expression is read-only, introduce a binding with 'Sequence.insert' to workaround" (* TODO: combi doing this *) - end; + end; *) Nobrace_transfo.remove_after (fun () -> apply_at_target_paths (scale_range_on factor index mark_let mark_for mark_contract_occs) tg ) @@ -1278,6 +1283,7 @@ let loop_single_on (i : int) (t : trm) : trm = let loop = trm_for l_range (trm_seq (Mlist.pop_front tl2)) in trm_seq_helper [ TrmMlist tl1; Trm loop ] +(* TODO : depreciate transformation *) let%transfo loop_single (tg : target) : unit = (apply_at_target_paths_in_seq loop_single_on) tg (** [elim_loop_single_on t]: Reverse the transformation loop_single_on. @@ -1304,6 +1310,7 @@ let elim_loop_single_on (t : trm) : trm = trm_seq_nobrace_nomarks (Mlist.to_list(Mlist.push_front index_start body)) +(* TODO : depreciate transformation *) (** [elim_loop_single tg]: Expects the target to point to a for loop. Applies [ elim_loop_single_on] *) let%transfo elim_loop_single (tg : target) : unit = @@ -1373,6 +1380,7 @@ let if_loop_switch_on (t : trm) : trm = let new_instrs = Mlist.replace_at 0 new_if instrs in trm_for ~mode new_lrange (trm_seq ?result:res new_instrs) ~contract +(* TODO : depreciate transformation *) let%transfo if_loop_switch (tg : target) = apply_at_target_paths if_loop_switch_on tg @@ -1441,6 +1449,7 @@ let refactor_if_in_loop_on (t : trm) : trm = } then_ ~contract +(* TODO : depreciate transformation *) let%transfo refactor_if_in_loop (tg : target) = apply_at_target_paths refactor_if_in_loop_on tg diff --git a/lib/transfo/loop_core.ml b/lib/transfo/loop_core.ml index cc71f6387..28d9ec5b0 100644 --- a/lib/transfo/loop_core.ml +++ b/lib/transfo/loop_core.ml @@ -79,7 +79,7 @@ let tile_on (tile_index : string) (bound : tile_bound) (tile_size : trm) (t : tr let inner_range = { index; start = (trm_int 0); direction = DirUp; stop = tile_size; step = trm_step_one () } in if not contract.strict then begin - if !Flags.check_validity then begin + (* if !Flags.check_validity then begin Trace.justif "loop range is checked to be dividable by tile size"; trm_seq_nobrace_nomarks [ div_check_assert; @@ -87,7 +87,7 @@ let tile_on (tile_index : string) (bound : tile_bound) (tile_size : trm) (t : tr trm_for ~mode inner_range (trm_subst_var index new_index body) ]) ] - end else + end else *) trm_for ~mode outer_range (trm_seq_nomarks [ trm_for ~mode inner_range (trm_subst_var index new_index body) ]) @@ -490,7 +490,7 @@ let split_range_at (nb : int) (cut : trm) let split_index = trm_add_mark mark_simpl split_index in let range1 = { range with stop = split_index } in let range2 = { range with start = split_index } in - let (pre_ghosts, post_ghosts) = if !Flags.check_validity then begin + let (pre_ghosts, post_ghosts) = if (* !Flags.check_validity *) Flags.annotated () then begin if not (Resources.trm_is_pure split_index) then trm_fail split_index "basic range splitting does not support non-pure split point"; let to_prove = Resource_trm.to_prove Resource_formula.(formula_is_subrange (formula_loop_range range1) (formula_loop_range range)) in diff --git a/lib/transfo/loop_swap.ml b/lib/transfo/loop_swap.ml index f95878598..b4f687837 100644 --- a/lib/transfo/loop_swap.ml +++ b/lib/transfo/loop_swap.ml @@ -57,7 +57,7 @@ let ghost_swap (outer_range: loop_range) inner_range (_, formula) = into: - // stars_j R(j) * V + // stars_j // stars_j SR(j,0) * stars_j UR(j) * stars_j stars_k PR(j,k) * stars_j FR(j) * SV(0) * UV * stars_k PV(k) * FV ghost rewrite stars_j stars_k PR(j,k) = stars_k stars_j PR(j,k) @@ -86,12 +86,12 @@ let swap_on (t: trm): trm = trm_seq (mlist (!(trm_for !__ !__ !__ !strict_loop_contract) ^:: nil)) __) !strict_loop_contract)) (fun outer_loop outer_range outer_mode inner_loop inner_range inner_mode body inner_contract outer_contract () -> - let open Resource_contract in + (* let open Resource_contract in if outer_contract.invariant <> Resource_set.empty then if not !Flags.check_validity then raise_notrace Pattern.Next else failwith "Loop.swap: the outer loop has sequential invariants"; - Trace.justif "outer loop was parallelizable (swapping loops can only remove possible interleavings)"; + Trace.justif "outer loop was parallelizable (swapping loops can only remove possible interleavings)"; *) let loop_ghosts = inner_contract.loop_ghosts in let inner_inv = inner_contract.invariant in @@ -140,7 +140,7 @@ let swap_on (t: trm): trm = swaps_post) ); Pattern.__ (fun () -> - if !Flags.check_validity then failwith "Loop.swap: not targeting two nested for-loop"; + (* if !Flags.check_validity then failwith "Loop.swap: not targeting two nested for-loop"; *) swap_on_any_loop t) ] @@ -253,7 +253,7 @@ let%transfo swap_basic (tg : target) : unit = let%transfo swap ?(mark_outer_loop : mark = no_mark) ?(mark_inner_loop : mark = no_mark) (tg : target) : unit = Target.iter (fun outer_loop_p -> Marks.with_marks (fun next_m -> - if not !Flags.check_validity then begin + if (* not !Flags.check_validity *) not (Flags.annotated ()) then begin swap_basic (target_of_path outer_loop_p); end else begin let _, seq_p = Path.index_in_seq outer_loop_p in diff --git a/lib/transfo/matrix.ml b/lib/transfo/matrix.ml index ee2257264..9f11c6e9a 100644 --- a/lib/transfo/matrix.ml +++ b/lib/transfo/matrix.ml @@ -2,6 +2,7 @@ open Prelude open Target include Matrix_basic +(* TODO : depreciate transformation *) (** [biject fun_bij tg]: expects the target [tg] to point at at a matrix declaration , then it will search for all its acccesses and replace MINDEX with [fun_bij]. *) let%transfo biject (fun_bij : var) (tg : target) : unit = @@ -102,6 +103,7 @@ let%transfo delocalize ?(mark : mark = no_mark) ?(init_zero : bool = false) ?(ac - (2) should start from replaced bottom leaf instead of top scope target? *) let simpl_void_loops = Loop.delete_all_void +(* TODO : depreciate transformation *) (** [elim]: eliminates the matrix [var] defined in at the declaration targeted by [tg]. All reads from [var] must be eliminated The values of [var] must only be read locally, i.e. directly after being written. *) @@ -123,6 +125,7 @@ let%transfo elim ?(simpl : target -> unit = simpl_void_loops) (tg : target) : un (* TODO: local_name_tile ~shift_to_zero *) (* + shift_to_zero ~nest_of *) +(* TODO : depreciate transformation *) (** [inline_constant]: expects [tg] to target a matrix definition, then first uses [Matrix.elim_mops] on all reads before attempting to use [Arrays.inline_constant]. @@ -136,6 +139,7 @@ let%transfo inline_constant ?(simpl : target -> unit = Arith.default_simpl) ~(de simpl [nbAny; cMark mark_accesses]; )) tg +(* TODO : depreciate transformation *) (** [elim_constant]: expects [tg] to target a matrix definition, then first uses [Matrix.elim_mops] on all reads before attempting to use [Arrays.elim_constant]. @@ -234,6 +238,7 @@ let%transfo local_name_tile end ) tg) +(* TODO : depreciate transformation *) (** same as {!local_name_tile} but with target [tg] pointing at an instruction within a sequence, introduces the local name for the rest of the sequence. *) let%transfo local_name_tile_after ?(delete: bool = false) ?(indices : string list = []) @@ -247,6 +252,7 @@ let%transfo local_name_tile_after ?(delete: bool = false) ?(indices : string lis Sequence.elim [cMark mark]; ) tg) +(* TODO : depreciate transformation *) let%transfo storage_folding ~(dim : int) ~(size : trm) ?(kind : storage_folding_kind = ModuloIndices) (tg : target) : unit = Trace.tag_valid_by_composition (); diff --git a/lib/transfo/matrix_basic.ml b/lib/transfo/matrix_basic.ml index 8d2fe071a..49466d9f8 100644 --- a/lib/transfo/matrix_basic.ml +++ b/lib/transfo/matrix_basic.ml @@ -14,12 +14,14 @@ let%transfo reorder_dims ~(base:trm) ?(rotate_n : int = 0) ?(order : int list = let%transfo insert_alloc_dim (new_dim : trm) (tg : target) : unit = Target.apply_at_target_paths (Matrix_core.insert_alloc_dim_aux new_dim) tg +(* TODO : depreciate transformation *) (** [insert_access_dim new_dim new_index tg]: expects the target [tg] to point at an array access, then it will add two new args([new_dim] and [new_index]) in the call to MINDEX function inside that array access. *) let%transfo insert_access_dim_index (new_dim : trm) (new_index : trm) (tg : target) : unit = Target.apply_at_target_paths (Matrix_core.insert_access_dim_index_aux new_dim new_index) tg +(* TODO : depreciate transformation *) (** [biject fun_name tg]: expectes the target [tg] to point at a function call, then it replaces the name of the called function with [fun_name]. *) let%transfo biject (fun_name : var) (tg : target) : unit = @@ -122,7 +124,7 @@ let ghost_shift ((range, formula): loop_range list * formula) ((shifted_range, shifted_formula): loop_range list * formula) (uninit_pre : bool) (uninit_post : bool): trm = - if !Flags.check_validity then (* FIXME: need more precise flag? *) + if (* !Flags.check_validity *) Flags.annotated () then (* FIXME: need more precise flag? *) (* FIXME: this can be explained as a sequence of calls to group_shift* ghosts *) let open Resource_formula in let before = List.fold_right (fun r f -> formula_group_range r f) range formula in @@ -259,7 +261,7 @@ let%transfo local_name_tile Nobrace_transfo.remove_after (fun _ -> Target.iter (fun p -> Marks.with_fresh_mark_on p (fun m -> let tile_dims_typ_model = ref None in - if !Flags.check_validity then begin + if (* !Flags.check_validity *) Flags.annotated () then begin (* find groups of mindex resource over !ret_var in context *) Resources.ensure_computed (); let var = !ret_var in @@ -344,7 +346,7 @@ let%transfo local_name_tile mark_dims mark_accesses mark_indices mark_alloc mark_load mark_unload !ret_var tile local_var dims elem_ty indices uninit_pre uninit_post model_before model_after ) p; - if !Flags.check_validity then begin + if (* !Flags.check_validity *) Flags.annotated () then begin Resources.ensure_computed (); if not !Flags.use_resources_with_models then begin let p = resolve_target_exactly_one [cMark m] in @@ -802,7 +804,7 @@ let%transfo stack_copy ~(var : var) ~(copy_var : string) ~(copy_dims : int) (tg Nobrace_transfo.remove_after (fun () -> Target.iter (fun p -> Marks.with_fresh_mark_on p (fun m -> Target.apply_at_path (stack_copy_on var copy_var copy_dims) p; - if !Flags.check_validity then begin + if (* !Flags.check_validity *) Flags.annotated () then begin Resources.ensure_computed (); (* TODO: is this exactly the same check as for Variable.local_name and Matrix.local_name? *) let t = get_trm_at_exn [cMark m] in @@ -845,6 +847,7 @@ let memset_apply_on ~(depth: int) ?(typ:typ option) (t : trm) :trm = List.iter check (List.combine ranges (List.combine dims indices)); Matrix_core.matrix_set ~typ:array_typ rhs array dims + (* TODO : depreciate transformation *) (** [memset] : Uses memset instead of for-loops initialization *) let%transfo memset ?(depth :int option) ?(typ:typ option) (tg:target) : unit = apply_at_target_paths (fun t -> @@ -985,6 +988,7 @@ let storage_folding_kind_to_string = function | ModuloIndices -> "ModuloIndices" | RotateVariables -> "RotateVariables" +(* TODO : depreciate transformation *) (** [storage_folding] expects target [tg] to point at a sequence defining matrix [var], and folds the [dim]-th dimension so that every index [i] into this matrix dimension is mapped to index [i % n]. diff --git a/lib/transfo/omp_basic.ml b/lib/transfo/omp_basic.ml index da254c3fc..5b1367433 100644 --- a/lib/transfo/omp_basic.ml +++ b/lib/transfo/omp_basic.ml @@ -11,63 +11,79 @@ open Target let%transfo atomic ?(ao : atomic_operation option) (tg : target) : unit = apply_at_target_paths (trm_add_pragma (Atomic ao)) tg +(* TODO : depreciate transformation *) let%transfo atomic_capture (tg : target) : unit = apply_at_target_paths (trm_add_pragma (Atomic_capture)) tg let%transfo barrier (tg : target) : unit = apply_at_target_paths (trm_add_pragma (Barrier)) tg +(* TODO : depreciate transformation *) let%transfo cancel ?(clause : clause list = []) (construct_type_clause : clause) (tg : target) : unit = apply_at_target_paths (trm_add_pragma (Cancel (construct_type_clause, clause))) tg +(* TODO : depreciate transformation *) let%transfo cancellation_point ?(clause : clause list = []) (construct_type_clause : clause) (tg : target) : unit = apply_at_target_paths (trm_add_pragma (Cancellation_point (construct_type_clause, clause))) tg +(* TODO : depreciate transformation *) let%transfo critical ?(hint : string = "") (v : var) (tg : target) : unit = apply_at_target_paths (trm_add_pragma (Critical (v, hint))) tg +(* TODO : depreciate transformation *) let%transfo declare_simd ?(clause : clause list = []) (tg : target) : unit = apply_at_target_paths (trm_add_pragma (Declare_simd clause )) tg +(* TODO : depreciate transformation *) let%transfo declare_reduction (ri : reduction_identifier) (tl : string list) (e : expression) (clause : clause) (tg : target) : unit = apply_at_target_paths (trm_add_pragma (Declare_reduction (ri, tl, e, clause))) tg +(* TODO : depreciate transformation *) let%transfo declare_target ?(clause : clause list = []) (tg : target) : unit = apply_at_target_paths (trm_add_pragma (Declare_target clause)) tg let%transfo distribute ?(clause : clause list = []) (tg : target) : unit = apply_at_target_paths (trm_add_pragma (Distribute clause)) tg +(* TODO : depreciate transformation *) let%transfo distribute_parallel_for ?(clause : clause list = []) (tg : target) : unit = apply_at_target_paths (trm_add_pragma (Distribute_parallel_for clause )) tg +(* TODO : depreciate transformation *) let%transfo distribute_parallel_for_simd ?(clause : clause list = []) (tg : target) : unit = apply_at_target_paths (trm_add_pragma (Distribute_parallel_for_simd clause )) tg +(* TODO : depreciate transformation *) let%transfo distribute_simd (tg : target) : unit = apply_at_target_paths (trm_add_pragma (Distribute_simd)) tg +(* TODO : depreciate transformation *) let%transfo end_declare_target (tg : target) : unit = apply_at_target_paths (trm_add_pragma (End_declare_target)) tg +(* TODO : depreciate transformation *) let%transfo flush (vl : vars) (tg : target) : unit = apply_at_target_paths (trm_add_pragma (Flush vl)) tg let add_pragma_on_parallelizable_for (directive: directive) (t: trm): trm = let error = "OMP transformation is invalid: it is not applied on a for loop." in let range, _, body, contract = trm_inv ~error trm_for_inv t in - if !Flags.check_validity then begin + (* Outside verification, useless with models *) + (* if !Flags.check_validity then begin let error = "OMP transformation is invalid" in Resources.justif_parallelizable_loop_contract ~error contract; - end; + end; *) trm_add_pragma directive (trm_like ~old:t (trm_for ~contract ~mode:Parallel range body)) +(* TODO : depreciate transformation *) let%transfo for_ ?(clause : clause list = []) (tg : target) : unit = apply_at_target_paths (add_pragma_on_parallelizable_for (For clause)) tg +(* TODO : depreciate transformation *) let%transfo for_simd ?(clause : clause list = []) (tg : target) : unit = apply_at_target_paths (add_pragma_on_parallelizable_for (For_simd clause)) tg +(* TODO : depreciate transformation *) let%transfo master (tg : target) : unit = apply_at_target_paths (trm_add_pragma (Master)) tg @@ -80,9 +96,11 @@ let%transfo parallel ?(clause : clause list = []) (tg : target) : unit = let%transfo parallel_for ?(clause : clause list = []) (tg : target) : unit = apply_at_target_paths (add_pragma_on_parallelizable_for (Parallel_for clause)) tg +(* TODO : depreciate transformation *) let%transfo parallel_for_simd ?(clause : clause list = []) (tg : target) : unit = apply_at_target_paths (add_pragma_on_parallelizable_for (Parallel_for_simd clause)) tg +(* TODO : depreciate transformation *) let%transfo parallel_sections ?(clause : clause list = []) (tg : target) : unit = apply_at_target_paths (trm_add_pragma (Parallel_sections clause)) tg @@ -98,233 +116,295 @@ let%transfo single ?(clause : clause list = []) (tg : target) : unit = let%transfo target ?(clause : clause list = []) (tg : target) : unit = apply_at_target_paths (trm_add_pragma (Target clause)) tg +(* TODO : depreciate transformation *) let%transfo target_data ?(clause : clause list = []) (tg : target) : unit = apply_at_target_paths (trm_add_pragma (Target_data clause)) tg +(* TODO : depreciate transformation *) let%transfo target_enter_data ?(clause : clause list = []) (tg : target) : unit = apply_at_target_paths (trm_add_pragma (Target_enter_data clause)) tg +(* TODO : depreciate transformation *) let%transfo target_exit_data ?(clause : clause list = []) (tg : target) : unit = apply_at_target_paths (trm_add_pragma (Target_exit_data clause)) tg +(* TODO : depreciate transformation *) let%transfo target_teams ?(clause : clause list = []) (tg : target) : unit = apply_at_target_paths (trm_add_pragma (Target_teams clause)) tg +(* TODO : depreciate transformation *) let%transfo target_teams_distribute ?(clause : clause list = []) (tg : target) : unit = apply_at_target_paths (trm_add_pragma (Target_teams_distribute clause)) tg +(* TODO : depreciate transformation *) let%transfo target_teams_distribute_parallel_for ?(clause : clause list = []) (tg : target) : unit = apply_at_target_paths (trm_add_pragma (Target_teams_distribute_parallel_for clause)) tg +(* TODO : depreciate transformation *) let%transfo target_teams_distribute_parallel_for_simd ?(clause : clause list = []) (tg : target) : unit = apply_at_target_paths (trm_add_pragma (Target_teams_distribute_parallel_for_simd clause)) tg +(* TODO : depreciate transformation *) let%transfo target_teams_distribute_simd ?(clause : clause list = []) (tg : target) : unit = apply_at_target_paths (trm_add_pragma (Target_teams_distribute_simd clause)) tg +(* TODO : depreciate transformation *) let%transfo target_update ?(clause : clause list = []) (tg : target) : unit = apply_at_target_paths (trm_add_pragma (Target_update clause)) tg +(* TODO : depreciate transformation *) let%transfo task ?(clause : clause list = []) (tg : target) : unit = apply_at_target_paths (trm_add_pragma (Task clause)) tg +(* TODO : depreciate transformation *) let%transfo taskgroup (tg : target) : unit = apply_at_target_paths (trm_add_pragma Taskgroup) tg +(* TODO : depreciate transformation *) let%transfo taskloop ?(clause : clause list = []) (tg : target) : unit = apply_at_target_paths (trm_add_pragma (Taskloop clause)) tg +(* TODO : depreciate transformation *) let%transfo taskloop_simd ?(clause : clause list = []) (tg : target) : unit = apply_at_target_paths (trm_add_pragma (Taskloop_simd clause)) tg +(* TODO : depreciate transformation *) let%transfo taskwait ?(clause : clause list = []) (tg : target) : unit = apply_at_target_paths (trm_add_pragma (Taskwait clause)) tg +(* TODO : depreciate transformation *) let%transfo taskyield (tg : target) : unit = apply_at_target_paths (trm_add_pragma Taskyield) tg +(* TODO : depreciate transformation *) let%transfo teams ?(clause : clause list = []) (tg : target) : unit = apply_at_target_paths (trm_add_pragma (Teams clause)) tg +(* TODO : depreciate transformation *) let%transfo teams_distribute ?(clause : clause list = []) (tg : target) : unit = apply_at_target_paths (trm_add_pragma (Teams_distribute clause)) tg +(* TODO : depreciate transformation *) let%transfo teams_distribute_end ?(clause : clause list = []) (tg : target) : unit = apply_at_target_paths (trm_add_pragma (Teams_distribute_end clause)) tg +(* TODO : depreciate transformation *) let%transfo teams_distribute_parallel_for ?(clause : clause list = []) (tg : target) : unit = apply_at_target_paths (trm_add_pragma (Teams_distribute_parallel_for clause)) tg +(* TODO : depreciate transformation *) let%transfo teams_distribute_parallel_for_simd ?(clause : clause list = []) (tg : target) : unit = apply_at_target_paths (trm_add_pragma (Teams_distribute_parallel_for_simd clause)) tg +(* TODO : depreciate transformation *) let%transfo threadprivate (vl : vars) (tg : target) : unit = apply_at_target_paths (trm_add_pragma (Threadprivate vl)) tg (******************************************************************************) (* OpenMP routines *) +(* TODO : depreciate transformation *) (******************************************************************************) let%transfo set_num_threads (nb_threads : int) (tg : target) : unit = apply_at_target_paths_before (fun t i -> Omp_core.set_num_threads_at nb_threads i t) tg +(* TODO : depreciate transformation *) let%transfo get_num_threads (nb_threads : var) (tg : target) : unit = apply_at_target_paths_before (fun t i -> Omp_core.get_num_threads_at nb_threads i t) tg +(* TODO : depreciate transformation *) let%transfo declare_num_threads ?(tg : target = [tFirst; dRoot]) (nb_threads : var) : unit = apply_at_target_paths_before (fun t i -> Omp_core.declare_num_threads_at nb_threads i t) tg +(* TODO : depreciate transformation *) let%transfo get_max_threads (max_threads : var) (tg : target) : unit = apply_at_target_paths_before (fun t i -> Omp_core.get_max_threads_at max_threads i t) tg +(* TODO : depreciate transformation *) let%transfo get_thread_num ?(const : bool = true) (thread_id : var) (tg : target) : unit = apply_at_target_paths_before (fun t i -> Omp_core.get_thread_num_at const thread_id i t) tg +(* TODO : depreciate transformation *) let%transfo get_num_procs (num_procs : var) (tg : target) : unit = apply_at_target_paths_before (fun t i -> Omp_core.get_num_procs_at num_procs i t) tg +(* TODO : depreciate transformation *) let%transfo in_parallel (in_parallel : var) (tg : target) : unit = apply_at_target_paths_before (fun t i -> Omp_core.in_parallel_at in_parallel i t) tg +(* TODO : depreciate transformation *) let%transfo set_dynamic (thread_id : int) (tg : target) : unit = apply_at_target_paths_before (fun t i -> Omp_core.set_dynamic_at thread_id i t) tg +(* TODO : depreciate transformation *) let%transfo get_dynamic (is_dynamic : var) (tg : target) : unit = apply_at_target_paths_before (fun t i -> Omp_core.get_dynamic_at is_dynamic i t) tg +(* TODO : depreciate transformation *) let%transfo get_cancellation (is_cancellation : var) (tg : target) : unit = apply_at_target_paths_before (fun t i -> Omp_core.get_cancellation_at is_cancellation i t) tg +(* TODO : depreciate transformation *) let%transfo set_nested (nested : int) (tg : target) : unit = apply_at_target_paths_before (fun t i -> Omp_core.set_nested_at nested i t) tg +(* TODO : depreciate transformation *) let%transfo get_nested (is_nested : var) (tg : target) : unit = apply_at_target_paths_before (fun t i -> Omp_core.get_nested_at is_nested i t) tg +(* TODO : depreciate transformation *) let%transfo set_schedule (sched_kind : sched_type) (modifier : int) (tg : target) : unit = apply_at_target_paths_before (fun t i -> Omp_core.set_schedule_at sched_kind modifier i t) tg +(* TODO : depreciate transformation *) let%transfo get_schedule (sched_kind : sched_type) (modifier : int) (tg : target) : unit = apply_at_target_paths_before (fun t i -> Omp_core.get_schedule_at sched_kind modifier i t) tg +(* TODO : depreciate transformation *) let%transfo get_thread_limit (limit : var) (tg : target) : unit = apply_at_target_paths_before (fun t i -> Omp_core.get_thread_limit_at limit i t) tg +(* TODO : depreciate transformation *) let%transfo set_max_active_levels (max_levels : int) (tg : target) : unit = apply_at_target_paths_before (fun t i -> Omp_core.set_max_active_levels_at max_levels i t) tg +(* TODO : depreciate transformation *) let%transfo get_max_active_levels (max_levels : var) (tg : target) : unit = apply_at_target_paths_before (fun t i -> Omp_core.get_max_active_levels_at max_levels i t) tg +(* TODO : depreciate transformation *) let%transfo get_level (level : var) (tg : target) : unit = apply_at_target_paths_before (fun t i -> Omp_core.get_level_at level i t) tg +(* TODO : depreciate transformation *) let%transfo get_ancestor_thread_num (thread_num : var) (tg : target) : unit = apply_at_target_paths_before (fun t i -> Omp_core.get_ancestor_thread_num_at thread_num i t) tg +(* TODO : depreciate transformation *) let%transfo get_team_size (level : int) (size : var) (tg : target) : unit = apply_at_target_paths_before (fun t i -> Omp_core.get_team_size_at level size i t) tg +(* TODO : depreciate transformation *) let%transfo get_active_level (active_level : var) (tg : target) : unit = apply_at_target_paths_before (fun t i -> Omp_core.get_active_level_at active_level i t) tg +(* TODO : depreciate transformation *) let%transfo in_final (in_final : var) (tg : target) : unit = apply_at_target_paths_before (fun t i -> Omp_core.in_final_at in_final i t) tg +(* TODO : depreciate transformation *) let%transfo set_default_device (device_num : var) (tg : target) : unit = apply_at_target_paths_before (fun t i -> Omp_core.set_default_device_at device_num i t) tg +(* TODO : depreciate transformation *) let%transfo get_default_device (default_device : var) (tg : target) : unit = apply_at_target_paths_before (fun t i -> Omp_core.get_default_device_at default_device i t) tg +(* TODO : depreciate transformation *) let%transfo get_proc_bind (proc_bind : var) (tg : target) : unit = apply_at_target_paths_before (fun t i -> Omp_core.get_proc_bind_at proc_bind i t) tg +(* TODO : depreciate transformation *) let%transfo get_num_devices (num_devices : var) (tg : target) : unit = apply_at_target_paths_before (fun t i -> Omp_core.get_num_devices_at num_devices i t) tg +(* TODO : depreciate transformation *) let%transfo get_num_teams (num_teams : var) (tg : target) : unit = apply_at_target_paths_before (fun t i -> Omp_core.get_num_teams_at num_teams i t) tg +(* TODO : depreciate transformation *) let%transfo get_team_num (team_num : var) (tg : target) : unit = apply_at_target_paths_before (fun t i -> Omp_core.get_team_num_at team_num i t) tg +(* TODO : depreciate transformation *) let%transfo is_initial_device (is_initial_device : var) (tg : target) : unit = apply_at_target_paths_before (fun t i -> Omp_core.is_initial_device_at is_initial_device i t) tg +(* TODO : depreciate transformation *) let%transfo init_lock (lock : var) (tg : target) : unit = apply_at_target_paths_before (fun t i -> Omp_core.init_lock_at lock i t) tg +(* TODO : depreciate transformation *) let%transfo init_nest_lock (lock : var) (tg : target) : unit = apply_at_target_paths_before (fun t i -> Omp_core.init_nest_lock_at lock i t) tg +(* TODO : depreciate transformation *) let%transfo destroy_lock (lock : var) (tg : target) : unit = apply_at_target_paths_before (fun t i -> Omp_core.destroy_lock_at lock i t) tg +(* TODO : depreciate transformation *) let%transfo destroy_nest_lock (lock : var) (tg : target) : unit = apply_at_target_paths_before (fun t i -> Omp_core.destroy_nest_lock_at lock i t) tg +(* TODO : depreciate transformation *) let%transfo set_lock (lock : var) (tg : target) : unit = apply_at_target_paths_before (fun t i -> Omp_core.set_lock_at lock i t) tg +(* TODO : depreciate transformation *) let%transfo set_nest_lock (lock : var) (tg : target) : unit = apply_at_target_paths_before (fun t i -> Omp_core.set_nest_lock_at lock i t) tg +(* TODO : depreciate transformation *) let%transfo unset_lock (lock : var) (tg : target) : unit = apply_at_target_paths_before (fun t i -> Omp_core.unset_lock_at lock i t) tg +(* TODO : depreciate transformation *) let%transfo unset_nest_lock (lock : var) (tg : target) : unit = apply_at_target_paths_before (fun t i -> Omp_core.unset_nest_lock_at lock i t) tg +(* TODO : depreciate transformation *) let%transfo test_lock (lock : var) (tg : target) : unit = apply_at_target_paths_before (fun t i -> Omp_core.test_lock_at lock i t) tg +(* TODO : depreciate transformation *) let%transfo test_nest_lock (lock : var) (tg : target) : unit = apply_at_target_paths_before (fun t i -> Omp_core.test_nest_lock_at lock i t) tg +(* TODO : depreciate transformation *) let%transfo get_wtime (wtime : var) (tg : target) : unit = apply_at_target_paths_before (fun t i -> Omp_core.get_wtime_at wtime i t) tg +(* TODO : depreciate transformation *) let%transfo get_wtick (wtick : var) (tg : target) : unit = apply_at_target_paths_before (fun t i -> Omp_core.get_wtick_at wtick i t) tg diff --git a/lib/transfo/record.ml b/lib/transfo/record.ml index 63f63574b..aaced4bd0 100644 --- a/lib/transfo/record.ml +++ b/lib/transfo/record.ml @@ -1,6 +1,7 @@ open Prelude include Record_basic +(* TODO : depreciate transformation *) (** [split_fields]: an extension to [Record_basic.split_fields]. It takes as argument ~(typ : typ) instead of ~(typ : typvar). *) diff --git a/lib/transfo/record_basic.ml b/lib/transfo/record_basic.ml index a06c1512f..52589de80 100644 --- a/lib/transfo/record_basic.ml +++ b/lib/transfo/record_basic.ml @@ -185,7 +185,7 @@ let split_fields_on (typvar : typvar) (field_list : (field * typ) list) let process_one_item ~(fold : bool) = process_matching_resource_item (fun wrap is_ro c -> process_one_cell ~fold wrap (is_ro, c)) (fun () -> []) in - let (unfolds, folds) = if !Flags.check_validity then begin + let (unfolds, folds) = if (* !Flags.check_validity *) Flags.annotated () then begin let (res_start, res_stop) = Resources.around_instrs span_instrs in let unfolds = List.concat_map (process_one_item ~fold:false) res_start.linear in let folds = List.concat_map (process_one_item ~fold:true) res_stop.linear in @@ -235,11 +235,11 @@ let split_fields_on (typvar : typvar) (field_list : (field * typ) list) trm_seq_nobrace_nomarks (folds @ [t]) in (* FIXME: duplicated code with set_explicit *) - let check_pure = if !Flags.check_validity then (fun name x -> + (* let check_pure = if !Flags.check_validity then (fun name x -> if Resources.trm_is_pure x then Trace.justif (sprintf "duplicated %s is pure" name) ) else (fun name x -> () - ) in + ) in *) let rec aux (t : trm) : trm = Pattern.pattern_match t [ Pattern.(trm_seq !__ !__) (fun instrs result () -> @@ -297,7 +297,7 @@ let split_fields_on (typvar : typvar) (field_list : (field * typ) list) ); Pattern.(trm_set !__ !__) (fun base value () -> Pattern.when_ (trm_ptr_typ_matches base); - check_pure "set value" value; + (* check_pure "set value" value; *) let set_one (sf, ty) = trm_set (trm_struct_access ~field_typ:ty ~struct_typ base sf) (trm_struct_get ~field_typ:ty ~struct_typ value sf) in @@ -347,6 +347,7 @@ let split_fields_on (typvar : typvar) (field_list : (field * typ) list) [ TrmList unfolds; TrmMlist span_instrs; TrmList folds ] ) +(* TODO : depreciate transformation *) (** [split_fields]: expects the target [tg] to point at a sequence span to perform the mapping: - `set(base, get(get_base))` --> `set(struct_access(base, f), get(struct_access(get_base, f))), ...` - `set(base, { .f = v; .. })` --> `set(struct_access(base, f) = v` @@ -368,14 +369,15 @@ let%transfo split_fields ~(typ : typvar) (tg : target) : unit = in let field_list = Internal.get_field_list struct_def in - if !Flags.check_validity then + (* if !Flags.check_validity then Trace.justif "correct if the produced code typechecks"; - + *) Nobrace_transfo.remove_after (fun () -> Target.iter (fun p -> let (p_seq, span) = Path.extract_last_dir_span p in Target.apply_at_path (split_fields_on typ field_list span) p_seq ) tg) +(* TODO : depreciate transformation *) (** [set_explicit tg]: expects the target [tg] to point at a set instruction where one struct instance has been assigned another struct instance. *) let%transfo set_explicit (tg : target) : unit = @@ -383,12 +385,14 @@ let%transfo set_explicit (tg : target) : unit = Nobrace_transfo.remove_after ( fun _ -> apply_at_target_paths (Record_core.set_explicit_on) tg) +(* TODO : depreciate transformation *) (** [set_implicit tg]: expects the target [tg] to point at a sequence containing a list of struct set assignments. And transforms it into a single struct assignment. So it is the inverse of set_explicit. *) let%transfo set_implicit (tg : target) : unit = apply_at_target_paths (Record_core.set_implicit_on) tg +(* TODO : depreciate transformation *) (** [reorder_fields order tg]: expects the target to be pointing at typedef struct or class. then it changes the order of the fields based on [order]. [order] - can be one of the following @@ -401,6 +405,7 @@ let%transfo set_implicit (tg : target) : unit = let%transfo reorder_fields (order : fields_order) (tg : target) : unit = apply_at_target_paths_in_seq (Record_core.reorder_fields_at order) tg +(* TODO : depreciate transformation *) (** [reveal_field ~reparse field_to_reveal_field tg]: expects the target [tg] to point at a typedef struct, then it will find [field_to_reveal_field] and it's underlying type and it will replace [field_to_reveal_field] with a list of fields rename comming from its underlying type. *) @@ -409,12 +414,14 @@ let%transfo reveal_field ?(reparse:bool=false) (field_to_reveal_field : field) ( (apply_at_target_paths_in_seq (Record_core.reveal_field_at field_to_reveal_field)) tg +(* TODO : depreciate transformation *) (** [reveal_fields fields_to_reveal_field tg]: an extension to the reveal_field transformation, this one is applied on multiple struct fields. *) let%transfo reveal_fields ?(reparse : bool = false) (fields_to_reveal_field : fields) (tg : target) : unit = List.iter (fun f -> reveal_field f tg) fields_to_reveal_field +(* TODO : depreciate transformation *) (** [to_variables tg]: expects the target [tg] to point at a variable declaration of type typedef Record. Then it will transform this declaration into a list of variable declarations where the type of these variables is inherited from the type of the struct definition. All the struct_accesses @@ -428,6 +435,7 @@ let%transfo to_variables (tg : target) : unit = ) ) tg +(* TODO : depreciate transformation *) (** [rename_fields rename tg] expects the target [tg] to point at a struct declaration, then it will rename all the fields that are matched when applying the type [rename] which can be a function to rename all the struct fields or only those that @@ -435,6 +443,7 @@ let%transfo to_variables (tg : target) : unit = let%transfo rename_fields (rename : rename) (tg : target) : unit = apply_at_target_paths_in_seq (fun i t -> Record_core.rename_fields_at i rename t) tg +(* TODO : depreciate transformation *) (** [applyto_fields_type ~reparse pattern typ_update tg]: expects the target [tg] to point at a struct definition, then it will update all the struct field types whose identifier matches [pattern]. *) let%transfo applyto_fields_type ?(reparse : bool = false) (pattern : string) (typ_update: typ -> typ) (tg : target) : unit = @@ -471,6 +480,7 @@ let struct_modif_simple ?(use_annot_of : bool = false) ?(new_fields : (label * t *) +(* TODO : depreciate transformation *) (** [change_field_access_kind acc_kind f tg]: expects the target [tg] to point a typedef, then it will find field [f] at change its access kind to [acc_kind]. *) let%transfo change_field_access_kind ?(field : field = "") (acc_kind : record_member_annot) (tg : target) : unit = @@ -481,6 +491,7 @@ let%transfo change_field_access_kind ?(field : field = "") (acc_kind : record_me let make_all_memebers_public : target -> unit = change_field_access_kind Access_public +(* TODO : depreciate transformation *) (** [method_to_const method_name]: expects the target [ŧg] to be pointing at a typedef record definition. Then it will check if the method of that record definition is already a const method or not. If it's a const method then this transformation does nothing, otherwise it will transform that method to a const one. diff --git a/lib/transfo/record_core.ml b/lib/transfo/record_core.ml index 9d6c59488..f14fbebd5 100644 --- a/lib/transfo/record_core.ml +++ b/lib/transfo/record_core.ml @@ -27,19 +27,19 @@ let set_explicit_on (t : trm) : trm = | _ -> trm_fail t (sprintf "could not get the declaration of typedef for %s" (var_to_string tid)) in let field_list = Internal.get_field_list struct_def in - let check_pure = if !Flags.check_validity then (fun name x -> + (* let check_pure = if !Flags.check_validity then (fun name x -> if Resources.trm_is_pure x then Trace.justif (sprintf "duplicated %s is pure" name) ) else (fun name x -> () - ) in + ) in *) (* already checked by set contract: check_pure "lhs" lt; *) - if !Flags.check_validity then Trace.justif "duplicated terms are pure"; + (* if !Flags.check_validity then Trace.justif "duplicated terms are pure"; *) (* clause is Reads or Writes *) let unfold_cells clause_locs = let open Resource_formula in let open Resource_contract in - if !Flags.check_validity then begin + if (* !Flags.check_validity *) Flags.annotated () then begin let make_admitted pure linear1 linear2 = Resource_trm.ghost_admitted { pre = Resource_set.make ~pure ~linear:linear1 (); @@ -107,7 +107,7 @@ let set_explicit_on (t : trm) : trm = (unfold_cells [Writes,lt], set_one) | _ -> (* other cases are included here *) (* lt = rt --> lt.f = rt.f *) - check_pure "rhs" rt; + (* check_pure "rhs" rt; *) let set_one i (sf, ty) = trm_set (trm_struct_access ~field_typ:ty ~struct_typ lt sf) (trm_struct_get ~field_typ:ty ~struct_typ rt sf) in diff --git a/lib/transfo/reduce.ml b/lib/transfo/reduce.ml index 6b6e09d1f..7063e06e9 100644 --- a/lib/transfo/reduce.ml +++ b/lib/transfo/reduce.ml @@ -1,3 +1,5 @@ +(* TODO Yanni : verify whether this file should be deleted/removed by deprecation *) + open Prelude open Target @@ -29,8 +31,9 @@ else trm_seq_nobrace_nomarks [], trm_seq_nobrace_nomarks [] in *) +(* Deprecated *) (** *) -let focus_reduce_item (input : trm) (i : trm) (j : trm) (n : trm) (m : trm) +(* let focus_reduce_item (input : trm) (i : trm) (j : trm) (n : trm) (m : trm) (wrapped_t : trm) : trm = let open Resource_formula in if !Flags.check_validity then @@ -39,13 +42,16 @@ let focus_reduce_item (input : trm) (i : trm) (j : trm) (n : trm) (m : trm) trm_seq_nobrace_nomarks [beg_focus; wrapped_t; end_focus] else wrapped_t - -let%transfo intro (tg : target) : unit = + *) +(* TODO : depreciate transformation *) +(* let%transfo intro (tg : target) : unit = let include_path = if !Flags.use_resources_with_models then "optitrust.h" else "optitrust_models.h" in Function.uninline ~f:[cInclude include_path; cFunDef "reduce_spe1"] tg + *) +(* Deprecated *) (** *) -let elim_basic_on (mark_alloc : mark) (mark_loop : mark) (to_expr : path) (t : trm) : trm = +(* let elim_basic_on (mark_alloc : mark) (mark_loop : mark) (to_expr : path) (t : trm) : trm = let prefix = ref None in let updated_t = Path.apply_on_path (fun red_t -> let error = "expected call to reduce" in @@ -86,19 +92,21 @@ let elim_basic_on (mark_alloc : mark) (mark_loop : mark) (to_expr : path) (t : t trm_var_get acc ) t to_expr in let prefix = Option.get !prefix in - trm_seq_nobrace_nomarks (prefix @ [updated_t]) + trm_seq_nobrace_nomarks (prefix @ [updated_t]) *) +(* TODO : depreciate transformation *) (** [elim_basic tg]: eliminates a call to [reduce], expanding it to a for loop. *) -let%transfo elim_basic ?(mark_alloc : mark = no_mark) ?(mark_loop : mark = no_mark) (tg : target) = +(* let%transfo elim_basic ?(mark_alloc : mark = no_mark) ?(mark_loop : mark = no_mark) (tg : target) = Nobrace_transfo.remove_after (fun () -> Target.iter (fun p -> let (to_instr, to_expr) = Path.path_in_instr p (Trace.ast ()) in Target.apply_at_path (elim_basic_on mark_alloc mark_loop to_expr) to_instr; if !Flags.check_validity then Trace.justif "valid by definition of reduce (not supporting negative ranges)" - ) tg) + ) tg) *) +(* Deprecated *) (** *) -let elim_inline_on (mark_simpl : mark) (red_p : path) (t : trm) : trm = +(* let elim_inline_on (mark_simpl : mark) (red_p : path) (t : trm) : trm = let focuses = ref (fun x -> x) in let t2 = Path.apply_on_path (fun red_t -> let error = "expected call to reduce" in @@ -131,25 +139,27 @@ let elim_inline_on (mark_simpl : mark) (red_p : path) (t : trm) : trm = | None -> trm_fail red_t "expected trivially constant loop range" ) t red_p in - if !Flags.check_validity then !focuses(t2) else t2 + if !Flags.check_validity then !focuses(t2) else t2 *) +(* TODO : depreciate transformation *) (** [elim_inline tg]: eliminates a call to [reduce], expanding it to an inlined expression. TODO: later, implement this as combi (1. unroll; 2. inline accumulator; 3. simplify zero add) *) -let%transfo elim_inline ?(mark_simpl : mark = no_mark) (tg : target) = +(* let%transfo elim_inline ?(mark_simpl : mark = no_mark) (tg : target) = Nobrace_transfo.remove_after (fun () -> Target.iter (fun p -> let instr_p, expr_p = Path.path_in_instr p (Trace.ast ()) in Target.apply_at_path (elim_inline_on mark_simpl expr_p) instr_p; if !Flags.check_validity then Trace.justif "valid by definition of reduce (not supporting negative ranges)" - ) tg) + ) tg) *) +(* TODO : depreciate transformation *) (** [elim_basic tg]: eliminates a call to [reduce], expanding it to a for loop. - [unroll]: whether the reduction loop should be unrolled - [inline]: whether the reduction variable should be inlined (implies [unroll]) *) -let%transfo elim ?(unroll : bool = false) ?(inline : bool = false) (tg : target) = +(* let%transfo elim ?(unroll : bool = false) ?(inline : bool = false) (tg : target) = Marks.with_marks (fun next_mark -> Target.iter (fun p -> if inline then begin @@ -162,10 +172,10 @@ let%transfo elim ?(unroll : bool = false) ?(inline : bool = false) (tg : target) if unroll then Loop.unroll [cMark mark_loop]; end ) tg - ) + ) *) (** *) -let slide_on (mark_alloc : mark) (mark_simpl : mark) (i : int) (t : trm) : trm = +(* let slide_on (mark_alloc : mark) (mark_simpl : mark) (i : int) (t : trm) : trm = (* FIXME: needs refactor, do at least unrolling with combi *) let error = "expected for loop" in let (range, mode, instrs, contract) = trm_inv ~error trm_for_inv_instrs t in @@ -281,20 +291,22 @@ let slide_on (mark_alloc : mark) (mark_simpl : mark) (i : int) (t : trm) : trm = Trm (trm_set out (trm_var_get acc)); TrmMlist after_instrs; ])); - ] + ] *) +(* TODO : depreciate transformation *) (** [slide_basic tg]: given a target to a call to [set(p, reduce)] within a perfectly nested loop: [for i in 0..n { set(p, reduce(... i ...)) }] allocates a variable outside the loop to compute next values based on previous values: [alloc s = reduce(... 0 ...); set(p[i := 0], s); for i in 1..n { set(s, f(s)); set(p, s) }] *) -let%transfo slide_basic ?(mark_alloc : mark = no_mark) ?(mark_simpl : mark = no_mark) +(* let%transfo slide_basic ?(mark_alloc : mark = no_mark) ?(mark_simpl : mark = no_mark) (tg : target) : unit = Nobrace_transfo.remove_after (fun () -> Target.iter (fun p -> let (i, loop_p) = Path.index_in_surrounding_loop p in Target.apply_at_path (slide_on mark_alloc mark_simpl i) loop_p; - ) tg) + ) tg) *) +(* TODO : depreciate transformation *) (** [slide tg]: given a target to a call to [set(p, reduce)] within a perfectly nested loop: [for i in 0..n { set(p, reduce(... i ...)) }] allocates a variable outside the loop to compute next values based on previous values: @@ -302,9 +314,9 @@ let%transfo slide_basic ?(mark_alloc : mark = no_mark) ?(mark_simpl : mark = no_ TODO: generate check that n > 0 *) -let%transfo slide ?(mark_alloc : mark = no_mark) ?(simpl : target -> unit = Arith.default_simpl) (tg : target) : unit = +(* let%transfo slide ?(mark_alloc : mark = no_mark) ?(simpl : target -> unit = Arith.default_simpl) (tg : target) : unit = Marks.with_marks (fun next_mark -> Target.iter (fun p -> let mark_simpl = next_mark () in slide_basic ~mark_alloc ~mark_simpl (target_of_path p); simpl [cMark mark_simpl]; - ) tg) + ) tg) *) diff --git a/lib/transfo/sequence_basic.ml b/lib/transfo/sequence_basic.ml index 512cb3f85..1acd914c5 100644 --- a/lib/transfo/sequence_basic.ml +++ b/lib/transfo/sequence_basic.ml @@ -22,10 +22,10 @@ let%transfo delete ?(nb_extra: int = 0) (tg : target) : unit = Target.iter (fun p -> let p_seq, span = Path.extract_last_dir_span p in let span = { span with stop = span.stop + nb_extra } in - if !Flags.check_validity && not !Flags.preserve_specs_only then begin + (* if !Flags.check_validity && not !Flags.preserve_specs_only then begin Resources.assert_instr_effects_shadowed p; Trace.justif "nothing modified by the instruction is observed later" - end; + end; *) apply_at_path (Sequence_core.delete_at span) p_seq ) tg diff --git a/lib/transfo/sequence_core.ml b/lib/transfo/sequence_core.ml index 9beab8ac6..a5a4ed5b0 100644 --- a/lib/transfo/sequence_core.ml +++ b/lib/transfo/sequence_core.ml @@ -31,10 +31,11 @@ let intro_at (mark : string) (label : label) (index : int) (nb : int) (t : trm) let index, nb = if nb < 0 then (index + nb + 1, -nb) else (index, nb) in let tl_before, tl_rest = Mlist.split index tl in let tl_seq, tl_after = Mlist.split ~left_bias:false nb tl_rest in - if !Flags.check_validity then begin + (* Deprecated with models *) + (* if !Flags.check_validity then begin Scope.assert_no_interference ~after_what:"the new sequence" ~on_interference:"out of scope" tl_seq tl_after; Trace.justif "local variables are not used after the new sequence" - end; + end; *) let tl_around = Mlist.merge tl_before tl_after in let intro_seq = trm_seq tl_seq in let intro_seq = trm_add_mark mark intro_seq in diff --git a/lib/transfo/stencil.ml b/lib/transfo/stencil.ml index 87a38ccc1..0f34397ed 100644 --- a/lib/transfo/stencil.ml +++ b/lib/transfo/stencil.ml @@ -4,6 +4,7 @@ open Prelude type nd_tile = Matrix_core.nd_tile +(* TODO : depreciate transformation *) let%transfo loop_align_stop_extend_start ~(start : trm) ~(stop : trm) ?(simpl : target -> unit = Arith.default_simpl) (tg : target) : unit = Trace.tag_valid_by_composition (); Target.iter (fun p -> @@ -18,6 +19,7 @@ let%transfo loop_align_stop_extend_start ~(start : trm) ~(stop : trm) ?(simpl : end ) tg (* TODO: remove following *) + (* TODO : depreciate transformation *) (* Trace.reparse (); simpl tg *) @@ -113,6 +115,7 @@ let collect_writes (p : path) : Var_set.t = ) ((target_of_path p) @ [nbAny; cVarDef ""]); !writes +(* TODO : depreciate transformation *) (* [tile]: allows fusing the stencils by chaining tiled computations, rather than chaining individual computations. [overlaps]: list of [var, overlap] pairs, where [var] is a variable being written to by a loop, that needs to be produced in tiles of [tile_size + overlap] due to following dependencies. diff --git a/lib/transfo/typedef_basic.ml b/lib/transfo/typedef_basic.ml index 88d45ff43..070bb13aa 100644 --- a/lib/transfo/typedef_basic.ml +++ b/lib/transfo/typedef_basic.ml @@ -22,6 +22,7 @@ let insert_copy (name : string) (tg : Target.target) : unit = (* FIXME: #advanced-scoping-check , deal with typedef names *) Nobrace_transfo.remove_after (fun _ -> Target.apply_at_target_paths (Typedef_core.insert_copy_of name) tg) +(* TODO : depreciate transformation *) (** [insert name td_body]: expects target [tg] to point at a relative location inside a sequence then it will insert a typedef declaration on that location. [name] - is the new type name while diff --git a/lib/transfo/variable.ml b/lib/transfo/variable.ml index 57151beb2..ad8dc9062 100644 --- a/lib/transfo/variable.ml +++ b/lib/transfo/variable.ml @@ -145,6 +145,7 @@ let%transfo delocalize ?(index : string = "dl_i") ?(mark : mark = no_mark) ?(ops Variable_basic.delocalize ~index ~array_size ~ops [cMark middle_mark]; ) +(* TODO : depreciate transformation *) (** [delocalize ~var ~into ~index ~mark ~ops ~array_size ~intos tg]: it's a continuation to the [delocalize] transformation that will unroll all the introduced loops from the basic delocalize transformation and convert the newly declared array to a list of variables namely for each index on variable, this variables should be given by the user through the labelled @@ -160,6 +161,7 @@ let%transfo delocalize_in_vars ?(index : string = "dl_i") ?(mark : mark = "secti Marks.remove "section_of_interest" [cMark "section_of_interest"] *) +(* TODO : depreciate transformation *) (** [intro_pattern_array ~pattern_aux_vars ~const ~pattern_vars ~pattern tg]: expects the target [tg] to be pointing to expressions of the form [pattern], then it will create an array of coefficients for each [pattern_vars] and replace the current coefficients with array accesses. *) diff --git a/lib/transfo/variable_basic.ml b/lib/transfo/variable_basic.ml index 86e5bff89..ccbc76fc8 100644 --- a/lib/transfo/variable_basic.ml +++ b/lib/transfo/variable_basic.ml @@ -22,13 +22,13 @@ let%transfo unfold ?(mark : mark = no_mark) ~(at : target) (tg : target) : unit Target.iter (fun p -> let t_decl = Target.resolve_path p in let x, _, init = trm_inv ~error:"Variable_core.unfold: expected a target to a variable definition" trm_let_inv t_decl in - if !Flags.check_validity then begin + (* if !Flags.check_validity then begin if Resources.trm_is_pure init then (* Case 1: pure expression *) Trace.justif "inlining a pure expression is always correct" else failwith "not yet implemented: factorize validity check with inlining" - end; + end; *) let init = trm_add_mark mark init in Target.apply_at_target_paths (trm_subst_var x init) at ) tg @@ -49,39 +49,39 @@ let%transfo inline ?(delete_decl : bool = true) ?(mark : mark = no_mark) (tg : t let tl, result = trm_inv ~error trm_seq_inv t_seq in let dl = Mlist.nth tl index in let x, _, init = trm_inv ~error:"expected a target to a variable definition" trm_let_inv dl in - if !Flags.use_resources_with_models then begin - (* when using models, type-checking is sufficient to check for correctness *) - let init = trm_add_mark mark init in - let res = Resources.after_trm init in - let init_model = trm_add_mark mark (Var_map.find Resource_set.var_result res.aliases) in - (* Printf.printf "rs: %s\n" (Resource_computation.resource_set_to_string res); - let init_model = (Option.unsome ~error:"expected init result" Resource_set.(find_pure var_result res)) in *) - let rec perform_subst_formula (f: formula): formula = - Pattern.pattern_match f [ - Pattern.(trm_specific_var x) (fun () -> trm_copy init_model); - Pattern.(__) (fun () -> trm_map perform_subst_formula f) - ] in - let rec perform_subst_trm (t: trm): trm = - let aux = trm_map ~f_formula:perform_subst_formula perform_subst_trm in - Pattern.pattern_match t [ - Pattern.(trm_specific_var x) (fun () -> trm_copy init); - Pattern.(trm_for !__ !__ !__ !__) (fun range mode body spec () -> - (* NOTE: erase contracts on the way, the inline expression might require more resources. *) - let t2 = aux t in - Pattern.pattern_match t2 [ - Pattern.(trm_for !__ !__ !__ !__) (fun range mode body spec () -> - let contract = { spec with strict = false } in - trm_for ~mode ~annot:t.annot ~contract range body - ) - ] - ); - Pattern.(__) (fun () -> aux t) - ] in - let new_tl = Mlist.update_at_index_and_fix_beyond ~delete:delete_decl index (fun t -> t) perform_subst_trm tl in - trm_seq ~annot:t_seq.annot ?result new_tl - end else begin + let init = trm_add_mark mark init in + let res = Resources.after_trm init in + let init_model = trm_add_mark mark (Var_map.find Resource_set.var_result res.aliases) in + (* Printf.printf "rs: %s\n" (Resource_computation.resource_set_to_string res); + let init_model = (Option.unsome ~error:"expected init result" Resource_set.(find_pure var_result res)) in *) + let rec perform_subst_formula (f: formula): formula = + Pattern.pattern_match f [ + Pattern.(trm_specific_var x) (fun () -> trm_copy init_model); + Pattern.(__) (fun () -> trm_map perform_subst_formula f) + ] in + let rec perform_subst_trm (t: trm): trm = + let aux = trm_map ~f_formula:perform_subst_formula perform_subst_trm in + Pattern.pattern_match t [ + Pattern.(trm_specific_var x) (fun () -> trm_copy init); + Pattern.(trm_for !__ !__ !__ !__) (fun range mode body spec () -> + (* NOTE: erase contracts on the way, the inline expression might require more resources. *) + let t2 = aux t in + Pattern.pattern_match t2 [ + Pattern.(trm_for !__ !__ !__ !__) (fun range mode body spec () -> + let contract = { spec with strict = false } in + trm_for ~mode ~annot:t.annot ~contract range body + ) + ] + ); + Pattern.(__) (fun () -> aux t) + ] in + let new_tl = Mlist.update_at_index_and_fix_beyond ~delete:delete_decl index (fun t -> t) perform_subst_trm tl in + trm_seq ~annot:t_seq.annot ?result new_tl (* LEGACY: shapes *) - if !Flags.check_validity then begin + (* Deprecated, legacy code *) + (* + end else begin + if !Flags.check_validity then begin if Resources.trm_is_pure init then (* Case 1: pure expression *) Trace.justif "inlining a pure expression is always correct" @@ -131,7 +131,7 @@ let%transfo inline ?(delete_decl : bool = true) ?(mark : mark = no_mark) (tg : t let init = trm_add_mark mark init in let new_tl = Mlist.update_at_index_and_fix_beyond ~delete:delete_decl index (fun t -> t) (trm_subst_var x init) tl in trm_seq ~annot:t_seq.annot ?result new_tl - end + end *) ) p_seq ) tg @@ -269,11 +269,11 @@ let%transfo insert ?(const : bool = false) ?(reparse : bool = false) ~(name : st Target.reparse_after ~reparse (Target.iter (fun p -> let (p_seq, i) = Path.extract_last_dir_before p in Target.apply_at_path (Variable_core.insert_at i const name typ value) p_seq; - if !Flags.check_validity then begin (* NOTE: same as instruction insertion *) + (* if !Flags.check_validity then begin (* NOTE: same as instruction insertion *) Resources.ensure_computed (); Resources.assert_instr_effects_shadowed (p_seq @ [Dir_seq_nth i]); Trace.justif "nothing modified by the instruction is observed later" - end + end *) )) tg (** [subst ~subst ~space tg]]: expects the target [tg] to point at any trm that could contain an occurrence of the @@ -281,7 +281,7 @@ let%transfo insert ?(const : bool = false) ?(reparse : bool = false) ~(name : st let%transfo subst ?(reparse : bool = false) ~(subst : var) ~(put : trm) (tg : target) : unit = Target.reparse_after ~reparse ( Target.iter (fun p -> - if !Flags.check_validity then begin + if (* !Flags.check_validity *) Flags.annotated () then begin let instr_p, expr_p = Path.path_in_instr p (Trace.ast ()) in Nobrace_transfo.remove_after (fun () -> (* FIXME: handle no brace in scope and typing to remove more lazily? *) Target.apply_at_path (fun instr_t -> @@ -375,7 +375,7 @@ let%transfo elim_reuse (tg : target) : unit = let _ = Path.apply_on_path (elim_analyse xy) (Trace.ast ()) p in let (x, y) = Option.get !xy in let (i, p_seq) = Path.index_in_seq p in - if !Flags.check_validity then begin + if (* !Flags.check_validity *) Flags.annotated () then begin step_backtrack ~discard_after:true (fun () -> Target.apply_at_path (fun t_seq -> let error = "expected sequence" in diff --git a/tests/accesses/scale/accesses_scale_basic.ml b/tests/accesses/scale/accesses_scale_basic.ml index 20f17f18d..529a481ba 100644 --- a/tests/accesses/scale/accesses_scale_basic.ml +++ b/tests/accesses/scale/accesses_scale_basic.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> (* TODO: !! Accesses_basic.scale ~factor:(trm_float 5.0) [cCellReadOrWrite ~base:[cVar "t"] ~index:[cVar "i"] ()]; *) diff --git a/tests/accesses/scale/accesses_scale_doc.ml b/tests/accesses/scale/accesses_scale_doc.ml index 4e1ee591b..aa3c0729e 100644 --- a/tests/accesses/scale/accesses_scale_doc.ml +++ b/tests/accesses/scale/accesses_scale_doc.ml @@ -1,9 +1,10 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true let _ = Flags.recompute_resources_between_steps := true - + *) let _ = Run.script_cpp (fun _ -> !! Accesses.scale_var ~factor:(trm_int 5) [cVarDef "x"]; (* TODO: !! Accesses.scale ~factor:(trm_float 5.0) [cVarDef "y"; cVar "x"]; *) diff --git a/tests/accesses/shift/accesses_shift_models.ml b/tests/accesses/shift/accesses_shift_models.ml index 6c06423d1..06ac7c37c 100644 --- a/tests/accesses/shift/accesses_shift_models.ml +++ b/tests/accesses/shift/accesses_shift_models.ml @@ -4,11 +4,11 @@ open Prelude let _ = Flags.check_validity := true let _ = Flags.recompute_resources_between_steps := true let _ = Flags.use_resources_with_models := true -let _ = Flags.preserve_specs_only := true +(* let _ = Flags.preserve_specs_only := true *) -let _ = Run.script_cpp (fun _ -> - !! Resources.ensure_computed (); +let _ = Run.script_cpp (fun _ -> () + (* !! Resources.ensure_computed (); (* FIXME: support double, etc, 5.0 *) !! Accesses.shift_var ~factor:(trm_int 5) [nbMulti; cTopFunDef "test_var"; cVarDef "x"]; - !! Accesses.shift_var ~factor:(trm_int 1) [nbMulti; cTopFunDef "test_var_inv"; cVarDef "s"]; + !! Accesses.shift_var ~factor:(trm_int 1) [nbMulti; cTopFunDef "test_var_inv"; cVarDef "s"]; *) ) From cdc15ace8c781bb7754458bf788dbed0ce53be02 Mon Sep 17 00:00:00 2001 From: "yanni.lefki" Date: Mon, 20 Jul 2026 15:31:32 +0200 Subject: [PATCH 12/23] deprecating non-model tests --- tests/accesses/scale/accesses_scale.ml | 5 +++-- tests/accesses/shift/accesses_shift.ml | 5 +++-- tests/accesses/shift/accesses_shift_basic.ml | 3 ++- tests/accesses/shift/accesses_shift_doc.ml | 5 +++-- tests/arith/simpl/arith_simpl.ml | 5 +++-- tests/arith/simpl/arith_simpl_doc.ml | 3 ++- tests/arith/sort/arith_sort.ml | 5 +++-- tests/function/delete/function_delete.ml | 3 ++- tests/function/elim_infix_ops/function_elim_infix_ops.ml | 3 ++- tests/function/inline/function_inline_doc.ml | 3 ++- tests/function/uninline/function_uninline.ml | 5 +++-- tests/function/uninline/function_uninline_basic.ml | 5 +++-- tests/function/use_infix_ops/function_use_infix_ops.ml | 3 ++- tests/function/use_infix_ops/function_use_infix_ops_basic.ml | 3 ++- tests/instr/gather/instr_gather.ml | 3 ++- tests/instr/gather/instr_gather_doc.ml | 3 ++- tests/instr/move/instr_move_basic.ml | 3 ++- tests/instr/move/instr_move_basic_doc.ml | 3 ++- tests/instr/move/instr_move_in_seq.ml | 3 ++- tests/interact/interact_traceview.ml | 3 ++- tests/interact/trace_query.ml | 3 ++- tests/interact/view_error.ml | 3 ++- tests/interact/view_type_error.ml | 3 ++- tests/loop/collapse/loop_collapse.ml | 3 ++- tests/loop/delete_void/loop_delete_void.ml | 3 ++- tests/loop/delete_void/loop_delete_void_basic.ml | 3 ++- tests/loop/fission/loop_fission.ml | 3 ++- tests/loop/fission/loop_fission_basic.ml | 3 ++- tests/loop/fission/loop_fission_basic_doc.ml | 3 ++- tests/loop/fusion/loop_fusion_basic.ml | 3 ++- tests/loop/fusion_targets/loop_fusion_targets.ml | 3 ++- tests/loop/hoist/loop_hoist_basic.ml | 3 ++- tests/loop/hoist/loop_hoist_basic_doc.ml | 3 ++- tests/loop/hoist_expr/loop_hoist_expr.ml | 3 ++- tests/loop/move/loop_move.ml | 3 ++- tests/loop/move/loop_move_doc.ml | 3 ++- tests/loop/moveout/loop_moveout.ml | 3 ++- tests/loop/moveout/loop_moveout_alloc_basic.ml | 3 ++- tests/loop/moveout/loop_moveout_basic.ml | 3 ++- tests/loop/moveout/loop_moveout_doc.ml | 3 ++- tests/loop/rename_index/loop_rename_index.ml | 3 ++- tests/loop/reorder_at/loop_reorder_at.ml | 5 +++-- tests/loop/reorder_at/loop_reorder_at_doc.ml | 3 ++- tests/loop/scale_range/loop_scale_range.ml | 5 +++-- tests/loop/scale_range/loop_scale_range_doc.ml | 5 +++-- tests/loop/shift_range/loop_shift_range.ml | 5 +++-- tests/loop/shift_range/loop_shift_range_basic.ml | 5 +++-- tests/loop/shift_range/loop_shift_range_basic_doc.ml | 3 ++- tests/loop/shift_range/loop_shift_range_doc.ml | 3 ++- tests/loop/split_range/loop_split_range.ml | 5 +++-- tests/loop/split_range/loop_split_range_doc.ml | 3 ++- tests/loop/swap/loop_swap.ml | 3 ++- tests/loop/swap/loop_swap_doc.ml | 3 ++- tests/loop/unroll/loop_unroll_basic.ml | 5 +++-- tests/loop/unroll/loop_unroll_basic_doc.ml | 3 ++- .../unroll_first_iterations/loop_unroll_first_iterations.ml | 5 +++-- .../loop_unroll_first_iterations_doc.ml | 3 ++- tests/loop/unswitch/loop_unswitch.ml | 3 ++- tests/loop/unswitch/loop_unswitch_doc.ml | 3 ++- tests/matrix/delete/matrix_delete.ml | 3 ++- tests/matrix/delete/matrix_delete_doc.ml | 3 ++- tests/matrix/elim_mops/matrix_elim_mops.ml | 3 ++- tests/matrix/local_name/matrix_local_name.ml | 5 +++-- tests/matrix/local_name/matrix_local_name_doc.ml | 3 ++- tests/matrix/local_name_tile/matrix_local_name_tile.ml | 5 +++-- tests/matrix/local_name_tile/matrix_local_name_tile_basic.ml | 3 ++- .../local_name_tile/matrix_local_name_tile_basic_doc.ml | 3 ++- tests/matrix/local_name_tile/matrix_local_name_tile_doc.ml | 3 ++- tests/matrix/reorder_dims/matrix_reorder_dims.ml | 3 ++- tests/matrix/stack_copy/matrix_stack_copy.ml | 5 +++-- tests/matrix/stack_copy/matrix_stack_copy_doc.ml | 3 ++- tests/perf/typing_big_perf.ml | 5 +++-- tests/perf/typing_perf.ml | 5 +++-- tests/record/set_explicit/record_set_explicit_basic.ml | 5 +++-- tests/record/set_explicit/record_set_explicit_basic_doc.ml | 3 ++- tests/record/to_variables/record_to_variables.ml | 5 +++-- .../resources/arbitrary_fracs/specialize_arbitrary_fracs.ml | 5 +++-- tests/resources/computation/aliases.ml | 5 +++-- tests/resources/computation/alloc.ml | 5 +++-- tests/resources/computation/array_write.ml | 5 +++-- tests/resources/computation/call_lambda.ml | 5 +++-- tests/resources/computation/fun_args.ml | 5 +++-- tests/resources/computation/ghost_args.ml | 5 +++-- tests/resources/computation/ghost_beta_reduce.ml | 5 +++-- tests/resources/computation/ghost_clear.ml | 5 +++-- tests/resources/computation/if.ml | 5 +++-- tests/resources/computation/incr.ml | 5 +++-- tests/resources/computation/let_ghost.ml | 5 +++-- tests/resources/computation/loop_contracts.ml | 5 +++-- tests/resources/computation/make_strict_loop_contract.ml | 5 +++-- tests/resources/computation/matmul_strict_annot.ml | 5 +++-- tests/resources/computation/matrix_alloc.ml | 5 +++-- tests/resources/computation/matrix_copy.ml | 5 +++-- tests/resources/computation/mut_var.ml | 5 +++-- tests/resources/computation/normalize_access.ml | 5 +++-- tests/resources/computation/optitrust_header.ml | 5 +++-- tests/resources/computation/read_only.ml | 5 +++-- tests/resources/computation/simplify_fracs.ml | 5 +++-- tests/resources/computation/uninit.ml | 5 +++-- tests/resources/contracts/detach_loop_ro_focus.ml | 3 ++- tests/resources/contracts/fix_types_in_contracts.ml | 5 +++-- tests/resources/contracts/fun_minimize.ml | 5 +++-- tests/resources/contracts/loop_minimize.ml | 5 +++-- tests/resources/ghost/ghost_embed_loop.ml | 5 +++-- tests/resources/ghost_pair/ghost_pair_distribute.ml | 3 ++- tests/resources/ghost_pair/ghost_pair_intro_elim.ml | 3 ++- tests/resources/ghost_pair/ghost_pair_intro_elim_lambda.ml | 3 ++- tests/resources/ghost_pair/ghost_pair_minimize.ml | 5 +++-- tests/resources/ghost_pair/move_in_loop.ml | 5 +++-- .../ghost_pure/ghost_pure_copy_surrounding_inside.ml | 5 +++-- tests/resources/ghost_pure/ghost_pure_fission.ml | 5 +++-- tests/resources/ghost_pure/ghost_pure_minimize.ml | 5 +++-- tests/resources/ghost_pure/ghost_pure_move_all_upwards.ml | 5 +++-- .../ghost_pure/ghost_pure_move_surrounding_inside.ml | 5 +++-- tests/resources_with_models/computation/optitrust_header.ml | 5 +++-- tests/sequence/delete/sequence_delete.ml | 3 ++- tests/sequence/elim/sequence_elim.ml | 3 ++- tests/sequence/elim_instr/sequence_elim_instr.ml | 3 ++- tests/sequence/elim_instr/sequence_elim_instr_doc.ml | 3 ++- tests/sequence/elim_let/sequence_elim_let.ml | 3 ++- tests/sequence/intro/sequence_intro.ml | 3 ++- tests/sequence/intro/sequence_intro_basic.ml | 3 ++- tests/sequence/intro/sequence_intro_basic_doc.ml | 3 ++- tests/sequence/intro/sequence_intro_doc.ml | 3 ++- tests/sequence/split/sequence_split.ml | 3 ++- tests/sequence/split/sequence_split_doc.ml | 3 ++- tests/stencil/fusion_targets/stencil_fusion_targets.ml | 3 ++- tests/variable/elim_reuse/variable_elim_reuse.ml | 3 ++- tests/variable/elim_reuse/variable_elim_reuse_doc.ml | 3 ++- tests/variable/init_attach/variable_init_attach.ml | 3 ++- tests/variable/init_detach/variable_init_detach.ml | 3 ++- tests/variable/init_detach/variable_init_detach_doc.ml | 3 ++- tests/variable/inline/variable_inline_basic.ml | 3 ++- tests/variable/local_name/variable_local_name.ml | 3 ++- tests/variable/subst/variable_subst.ml | 5 +++-- tests/variable/subst/variable_subst_doc.ml | 5 +++-- 136 files changed, 331 insertions(+), 195 deletions(-) diff --git a/tests/accesses/scale/accesses_scale.ml b/tests/accesses/scale/accesses_scale.ml index ea92b73bc..174c736ad 100644 --- a/tests/accesses/scale/accesses_scale.ml +++ b/tests/accesses/scale/accesses_scale.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) let _ = Run.script_cpp (fun _ -> diff --git a/tests/accesses/shift/accesses_shift.ml b/tests/accesses/shift/accesses_shift.ml index 01fdb1d73..e96b371e9 100644 --- a/tests/accesses/shift/accesses_shift.ml +++ b/tests/accesses/shift/accesses_shift.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) let _ = Run.script_cpp (fun _ -> !! Accesses.shift_var ~factor:(trm_float 5.0) [nbMulti; cTopFunDef "test_var"; cVarDef "x"]; diff --git a/tests/accesses/shift/accesses_shift_basic.ml b/tests/accesses/shift/accesses_shift_basic.ml index 10195e45a..5962be2a2 100644 --- a/tests/accesses/shift/accesses_shift_basic.ml +++ b/tests/accesses/shift/accesses_shift_basic.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> !! () diff --git a/tests/accesses/shift/accesses_shift_doc.ml b/tests/accesses/shift/accesses_shift_doc.ml index 7cdf35e4e..aa64982da 100644 --- a/tests/accesses/shift/accesses_shift_doc.ml +++ b/tests/accesses/shift/accesses_shift_doc.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) let _ = Run.script_cpp (fun _ -> diff --git a/tests/arith/simpl/arith_simpl.ml b/tests/arith/simpl/arith_simpl.ml index 16eb199d0..27402f927 100644 --- a/tests/arith/simpl/arith_simpl.ml +++ b/tests/arith/simpl/arith_simpl.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) let _ = Run.script_cpp (fun _ -> (* TODO: split this files into one file for each type of simplification *) diff --git a/tests/arith/simpl/arith_simpl_doc.ml b/tests/arith/simpl/arith_simpl_doc.ml index cc91baa41..cdb9f33fb 100644 --- a/tests/arith/simpl/arith_simpl_doc.ml +++ b/tests/arith/simpl/arith_simpl_doc.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> diff --git a/tests/arith/sort/arith_sort.ml b/tests/arith/sort/arith_sort.ml index 527932baf..f56cb7747 100644 --- a/tests/arith/sort/arith_sort.ml +++ b/tests/arith/sort/arith_sort.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) let _ = Run.script_cpp (fun _ -> diff --git a/tests/function/delete/function_delete.ml b/tests/function/delete/function_delete.ml index 551376854..ebe6a1802 100644 --- a/tests/function/delete/function_delete.ml +++ b/tests/function/delete/function_delete.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> !! Function.delete [cFunDef "f"]; diff --git a/tests/function/elim_infix_ops/function_elim_infix_ops.ml b/tests/function/elim_infix_ops/function_elim_infix_ops.ml index 6d7f70113..4b45a420b 100644 --- a/tests/function/elim_infix_ops/function_elim_infix_ops.ml +++ b/tests/function/elim_infix_ops/function_elim_infix_ops.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> diff --git a/tests/function/inline/function_inline_doc.ml b/tests/function/inline/function_inline_doc.ml index 7b0b078bd..415abce5b 100644 --- a/tests/function/inline/function_inline_doc.ml +++ b/tests/function/inline/function_inline_doc.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> diff --git a/tests/function/uninline/function_uninline.ml b/tests/function/uninline/function_uninline.ml index 40e186302..3cfcfdbc0 100644 --- a/tests/function/uninline/function_uninline.ml +++ b/tests/function/uninline/function_uninline.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) let _ = Run.script_cpp (fun _ -> !! Function.uninline ~f:[cTopFunDef "f"] [cVarDef "b"]; diff --git a/tests/function/uninline/function_uninline_basic.ml b/tests/function/uninline/function_uninline_basic.ml index 3e9b61e84..f9fcbb275 100644 --- a/tests/function/uninline/function_uninline_basic.ml +++ b/tests/function/uninline/function_uninline_basic.ml @@ -1,3 +1,4 @@ +(* Deprecated *) open Optitrust open Target @@ -9,8 +10,8 @@ open Target in the future, we may want to introduce an annotation to allow preserving the presentation used by the original code in case it involves a star. *) -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) let _ = Run.script_cpp (fun _ -> let tLabelSpan label = tSpan [tAfter; cLabel (label ^ "_start")] [tBefore; cLabel (label ^ "_end")] in diff --git a/tests/function/use_infix_ops/function_use_infix_ops.ml b/tests/function/use_infix_ops/function_use_infix_ops.ml index 0533ee4ff..ddaa65148 100644 --- a/tests/function/use_infix_ops/function_use_infix_ops.ml +++ b/tests/function/use_infix_ops/function_use_infix_ops.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> diff --git a/tests/function/use_infix_ops/function_use_infix_ops_basic.ml b/tests/function/use_infix_ops/function_use_infix_ops_basic.ml index 1942617b6..3e4b91dfc 100644 --- a/tests/function/use_infix_ops/function_use_infix_ops_basic.ml +++ b/tests/function/use_infix_ops/function_use_infix_ops_basic.ml @@ -1,9 +1,10 @@ +(* Deprecated *) open Optitrust open Prelude (* ARTHUR: add an efficient mechanism for targeting all potential infix ops in depth *) -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> diff --git a/tests/instr/gather/instr_gather.ml b/tests/instr/gather/instr_gather.ml index b49248c3d..1d77cc5a8 100644 --- a/tests/instr/gather/instr_gather.ml +++ b/tests/instr/gather/instr_gather.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> (* TODO: flag to prevent moving deps diff --git a/tests/instr/gather/instr_gather_doc.ml b/tests/instr/gather/instr_gather_doc.ml index 18df087a5..b720134df 100644 --- a/tests/instr/gather/instr_gather_doc.ml +++ b/tests/instr/gather/instr_gather_doc.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> diff --git a/tests/instr/move/instr_move_basic.ml b/tests/instr/move/instr_move_basic.ml index ceb43f6c6..a0513e0da 100644 --- a/tests/instr/move/instr_move_basic.ml +++ b/tests/instr/move/instr_move_basic.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> !! Instr_basic.move ~dest:[tBefore;cVarDef "x"] [cVarDef "z"]; diff --git a/tests/instr/move/instr_move_basic_doc.ml b/tests/instr/move/instr_move_basic_doc.ml index e5196003b..7f5e87476 100644 --- a/tests/instr/move/instr_move_basic_doc.ml +++ b/tests/instr/move/instr_move_basic_doc.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Flags.dump_ast_details := true let _ = Run.script_cpp (fun _ -> diff --git a/tests/instr/move/instr_move_in_seq.ml b/tests/instr/move/instr_move_in_seq.ml index 4e25a8a06..77252dfaf 100644 --- a/tests/instr/move/instr_move_in_seq.ml +++ b/tests/instr/move/instr_move_in_seq.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Flags.dump_ast_details := true let _ = Run.script_cpp (fun _ -> diff --git a/tests/interact/interact_traceview.ml b/tests/interact/interact_traceview.ml index e8ddbed92..b45e437ac 100644 --- a/tests/interact/interact_traceview.ml +++ b/tests/interact/interact_traceview.ml @@ -1,9 +1,10 @@ +(* Deprecated *) open Optitrust open Prelude (** This unit test is for testing the trace generation *) -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) (* Use the line below to generate a smaller trace with ast only for big and small steps diff --git a/tests/interact/trace_query.ml b/tests/interact/trace_query.ml index 4fb317c2c..3ec9b2952 100644 --- a/tests/interact/trace_query.ml +++ b/tests/interact/trace_query.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Flags.execution_mode := Execution_mode_full_trace let _ = Run.script_cpp ~filename:"interact_traceview.cpp" (fun _ -> diff --git a/tests/interact/view_error.ml b/tests/interact/view_error.ml index f75523247..27b023614 100644 --- a/tests/interact/view_error.ml +++ b/tests/interact/view_error.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> diff --git a/tests/interact/view_type_error.ml b/tests/interact/view_type_error.ml index 219bb5531..73c489bfd 100644 --- a/tests/interact/view_type_error.ml +++ b/tests/interact/view_type_error.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> diff --git a/tests/loop/collapse/loop_collapse.ml b/tests/loop/collapse/loop_collapse.ml index 34117e958..fc96e0647 100644 --- a/tests/loop/collapse/loop_collapse.ml +++ b/tests/loop/collapse/loop_collapse.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> (* TODO: eliminate assumes *) diff --git a/tests/loop/delete_void/loop_delete_void.ml b/tests/loop/delete_void/loop_delete_void.ml index d43a08edf..bb94e6bd8 100644 --- a/tests/loop/delete_void/loop_delete_void.ml +++ b/tests/loop/delete_void/loop_delete_void.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp(fun _ -> !! Loop.delete_void [cFor "i"]; diff --git a/tests/loop/delete_void/loop_delete_void_basic.ml b/tests/loop/delete_void/loop_delete_void_basic.ml index 24e3d3d86..ad75076aa 100644 --- a/tests/loop/delete_void/loop_delete_void_basic.ml +++ b/tests/loop/delete_void/loop_delete_void_basic.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp(fun _ -> !! Loop_basic.delete_void [cFor "i"]; diff --git a/tests/loop/fission/loop_fission.ml b/tests/loop/fission/loop_fission.ml index 77cbff244..27d4d2d43 100644 --- a/tests/loop/fission/loop_fission.ml +++ b/tests/loop/fission/loop_fission.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp ( fun _ -> !! Loop.fission [cFunBody "pure"; cForBody ~body:[cVarDef "d"] "i"; tBetweenAll]; diff --git a/tests/loop/fission/loop_fission_basic.ml b/tests/loop/fission/loop_fission_basic.ml index 6c86c6844..9218003a7 100644 --- a/tests/loop/fission/loop_fission_basic.ml +++ b/tests/loop/fission/loop_fission_basic.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp ( fun _ -> (* 1. Parallel loops can be fissioned, unless binders are broken. *) diff --git a/tests/loop/fission/loop_fission_basic_doc.ml b/tests/loop/fission/loop_fission_basic_doc.ml index 17828689c..612ec87be 100644 --- a/tests/loop/fission/loop_fission_basic_doc.ml +++ b/tests/loop/fission/loop_fission_basic_doc.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := false +(* let _ = Flags.check_validity := false *) let _ = Run.script_cpp (fun _ -> diff --git a/tests/loop/fusion/loop_fusion_basic.ml b/tests/loop/fusion/loop_fusion_basic.ml index 715243699..2c27ee52b 100644 --- a/tests/loop/fusion/loop_fusion_basic.ml +++ b/tests/loop/fusion/loop_fusion_basic.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp ( fun _ -> (* 1. Parallel loops can be fusioned *) diff --git a/tests/loop/fusion_targets/loop_fusion_targets.ml b/tests/loop/fusion_targets/loop_fusion_targets.ml index 328390842..db5500aa8 100644 --- a/tests/loop/fusion_targets/loop_fusion_targets.ml +++ b/tests/loop/fusion_targets/loop_fusion_targets.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp ( fun _ -> !! Loop.fusion_targets [cFunBody "f"; multi cFor ["i"; "j"]]; diff --git a/tests/loop/hoist/loop_hoist_basic.ml b/tests/loop/hoist/loop_hoist_basic.ml index 4f7ed1502..9a5f87a77 100644 --- a/tests/loop/hoist/loop_hoist_basic.ml +++ b/tests/loop/hoist/loop_hoist_basic.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Prelude open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun () -> let (x, _) = find_var "x" [] in diff --git a/tests/loop/hoist/loop_hoist_basic_doc.ml b/tests/loop/hoist/loop_hoist_basic_doc.ml index 18b9ab84b..ea41207a7 100644 --- a/tests/loop/hoist/loop_hoist_basic_doc.ml +++ b/tests/loop/hoist/loop_hoist_basic_doc.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Prelude open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> let (x, _) = find_var "x" [] in diff --git a/tests/loop/hoist_expr/loop_hoist_expr.ml b/tests/loop/hoist_expr/loop_hoist_expr.ml index cf35f7360..38d54652a 100644 --- a/tests/loop/hoist_expr/loop_hoist_expr.ml +++ b/tests/loop/hoist_expr/loop_hoist_expr.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun () -> !! Loop.hoist_expr ~dest:[tBefore; cFor "i"] "t2" [cFor "i"; cArrayRead "t"]; diff --git a/tests/loop/move/loop_move.ml b/tests/loop/move/loop_move.ml index 2b5e6fc8f..72cdc92e5 100644 --- a/tests/loop/move/loop_move.ml +++ b/tests/loop/move/loop_move.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> !! Loop.move [occFirst; cFor "y"] ~before:[cFor "x"]; diff --git a/tests/loop/move/loop_move_doc.ml b/tests/loop/move/loop_move_doc.ml index ccebbe2df..f7afceb2e 100644 --- a/tests/loop/move/loop_move_doc.ml +++ b/tests/loop/move/loop_move_doc.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun () -> diff --git a/tests/loop/moveout/loop_moveout.ml b/tests/loop/moveout/loop_moveout.ml index 6a49148cd..39a6ea3ba 100644 --- a/tests/loop/moveout/loop_moveout.ml +++ b/tests/loop/moveout/loop_moveout.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> !! Loop.move_out ~upto:"i" [cVarDef "x"]; diff --git a/tests/loop/moveout/loop_moveout_alloc_basic.ml b/tests/loop/moveout/loop_moveout_alloc_basic.ml index d91d1301d..c1b3f02f0 100644 --- a/tests/loop/moveout/loop_moveout_alloc_basic.ml +++ b/tests/loop/moveout/loop_moveout_alloc_basic.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> !! Loop_basic.move_out_alloc [cFunBody "simple"; sInstr "m ="]; diff --git a/tests/loop/moveout/loop_moveout_basic.ml b/tests/loop/moveout/loop_moveout_basic.ml index cdff331e9..48d5b1472 100644 --- a/tests/loop/moveout/loop_moveout_basic.ml +++ b/tests/loop/moveout/loop_moveout_basic.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> diff --git a/tests/loop/moveout/loop_moveout_doc.ml b/tests/loop/moveout/loop_moveout_doc.ml index fd8b4cb2f..c47d45b6c 100644 --- a/tests/loop/moveout/loop_moveout_doc.ml +++ b/tests/loop/moveout/loop_moveout_doc.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> !! Loop.move_out [cVarDef "s"]; diff --git a/tests/loop/rename_index/loop_rename_index.ml b/tests/loop/rename_index/loop_rename_index.ml index b099d59ca..b928ed140 100644 --- a/tests/loop/rename_index/loop_rename_index.ml +++ b/tests/loop/rename_index/loop_rename_index.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> !! Loop_basic.rename_index "i2" [cFunDef "main"; cFor "i"]; diff --git a/tests/loop/reorder_at/loop_reorder_at.ml b/tests/loop/reorder_at/loop_reorder_at.ml index ecbd87ee3..61491c00f 100644 --- a/tests/loop/reorder_at/loop_reorder_at.ml +++ b/tests/loop/reorder_at/loop_reorder_at.ml @@ -1,9 +1,10 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) let _ = Run.script_cpp (fun _ -> (* TODO: minimize contracts *) diff --git a/tests/loop/reorder_at/loop_reorder_at_doc.ml b/tests/loop/reorder_at/loop_reorder_at_doc.ml index 67fd7abca..356981b17 100644 --- a/tests/loop/reorder_at/loop_reorder_at_doc.ml +++ b/tests/loop/reorder_at/loop_reorder_at_doc.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> !! Loop.reorder_at ~order:["c";"b"] [cFunBody "f1"; cForBody "c"; dSeqNth 0]; diff --git a/tests/loop/scale_range/loop_scale_range.ml b/tests/loop/scale_range/loop_scale_range.ml index f1a47f097..f0bb4e157 100644 --- a/tests/loop/scale_range/loop_scale_range.ml +++ b/tests/loop/scale_range/loop_scale_range.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) let _ = Run.script_cpp(fun _ -> !! Loop.scale_range ~index:"i_s" ~factor:(trm_int 2) [cFunBody "f"; cFor "i"]; diff --git a/tests/loop/scale_range/loop_scale_range_doc.ml b/tests/loop/scale_range/loop_scale_range_doc.ml index bb8fa670a..a7365184a 100644 --- a/tests/loop/scale_range/loop_scale_range_doc.ml +++ b/tests/loop/scale_range/loop_scale_range_doc.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) let _ = Run.script_cpp (fun _ -> diff --git a/tests/loop/shift_range/loop_shift_range.ml b/tests/loop/shift_range/loop_shift_range.ml index 6fb158339..0e8b72557 100644 --- a/tests/loop/shift_range/loop_shift_range.ml +++ b/tests/loop/shift_range/loop_shift_range.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) let _ = Run.script_cpp(fun _ -> !! Loop.shift_range ~index:"i_s" (ShiftBy (trm_int 2)) [cFunDef "f"; cFor "i"]; diff --git a/tests/loop/shift_range/loop_shift_range_basic.ml b/tests/loop/shift_range/loop_shift_range_basic.ml index 2de781058..0e4b5cb40 100644 --- a/tests/loop/shift_range/loop_shift_range_basic.ml +++ b/tests/loop/shift_range/loop_shift_range_basic.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) let _ = Run.script_cpp(fun _ -> !! Loop_basic.shift_range "i2" (ShiftBy (trm_int 2)) [cFunBody "seq_array"; cFor "i"]; diff --git a/tests/loop/shift_range/loop_shift_range_basic_doc.ml b/tests/loop/shift_range/loop_shift_range_basic_doc.ml index d6651844e..40b028f32 100644 --- a/tests/loop/shift_range/loop_shift_range_basic_doc.ml +++ b/tests/loop/shift_range/loop_shift_range_basic_doc.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> !! Loop_basic.shift_range "i2" StartAtZero [cFor "i"]; diff --git a/tests/loop/shift_range/loop_shift_range_doc.ml b/tests/loop/shift_range/loop_shift_range_doc.ml index 7538691ec..30dea11be 100644 --- a/tests/loop/shift_range/loop_shift_range_doc.ml +++ b/tests/loop/shift_range/loop_shift_range_doc.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> !! Loop.shift_range ~index:"i2" StartAtZero [cFor "i"]; diff --git a/tests/loop/split_range/loop_split_range.ml b/tests/loop/split_range/loop_split_range.ml index e728849c1..b5045c3cd 100644 --- a/tests/loop/split_range/loop_split_range.ml +++ b/tests/loop/split_range/loop_split_range.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) let _ = Run.script_cpp(fun _ -> diff --git a/tests/loop/split_range/loop_split_range_doc.ml b/tests/loop/split_range/loop_split_range_doc.ml index 5aaf789c5..a0e34176e 100644 --- a/tests/loop/split_range/loop_split_range_doc.ml +++ b/tests/loop/split_range/loop_split_range_doc.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> diff --git a/tests/loop/swap/loop_swap.ml b/tests/loop/swap/loop_swap.ml index 31d08f606..866f66899 100644 --- a/tests/loop/swap/loop_swap.ml +++ b/tests/loop/swap/loop_swap.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> !! Loop.swap_basic [cFunBody "demo_both_par"; cFor "i"]; diff --git a/tests/loop/swap/loop_swap_doc.ml b/tests/loop/swap/loop_swap_doc.ml index 4ac9c3437..f1b98d238 100644 --- a/tests/loop/swap/loop_swap_doc.ml +++ b/tests/loop/swap/loop_swap_doc.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> diff --git a/tests/loop/unroll/loop_unroll_basic.ml b/tests/loop/unroll/loop_unroll_basic.ml index 6ae23ccd3..545ba11d9 100644 --- a/tests/loop/unroll/loop_unroll_basic.ml +++ b/tests/loop/unroll/loop_unroll_basic.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) let _ = Run.script_cpp (fun _ -> diff --git a/tests/loop/unroll/loop_unroll_basic_doc.ml b/tests/loop/unroll/loop_unroll_basic_doc.ml index 7fdb7a708..e09195b02 100644 --- a/tests/loop/unroll/loop_unroll_basic_doc.ml +++ b/tests/loop/unroll/loop_unroll_basic_doc.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> diff --git a/tests/loop/unroll_first_iterations/loop_unroll_first_iterations.ml b/tests/loop/unroll_first_iterations/loop_unroll_first_iterations.ml index 2025e83bc..9c9862dd6 100644 --- a/tests/loop/unroll_first_iterations/loop_unroll_first_iterations.ml +++ b/tests/loop/unroll_first_iterations/loop_unroll_first_iterations.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) let _ = Run.script_cpp (fun () -> diff --git a/tests/loop/unroll_first_iterations/loop_unroll_first_iterations_doc.ml b/tests/loop/unroll_first_iterations/loop_unroll_first_iterations_doc.ml index e737dbfb5..ce25ad820 100644 --- a/tests/loop/unroll_first_iterations/loop_unroll_first_iterations_doc.ml +++ b/tests/loop/unroll_first_iterations/loop_unroll_first_iterations_doc.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun () -> diff --git a/tests/loop/unswitch/loop_unswitch.ml b/tests/loop/unswitch/loop_unswitch.ml index adefd10b1..c04414383 100644 --- a/tests/loop/unswitch/loop_unswitch.ml +++ b/tests/loop/unswitch/loop_unswitch.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> !! Loop_basic.unswitch [cIf ~cond:[cBool true] ()]; diff --git a/tests/loop/unswitch/loop_unswitch_doc.ml b/tests/loop/unswitch/loop_unswitch_doc.ml index 923f9b9b7..7ef361fec 100644 --- a/tests/loop/unswitch/loop_unswitch_doc.ml +++ b/tests/loop/unswitch/loop_unswitch_doc.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> diff --git a/tests/matrix/delete/matrix_delete.ml b/tests/matrix/delete/matrix_delete.ml index c396de24d..6a9c469d3 100644 --- a/tests/matrix/delete/matrix_delete.ml +++ b/tests/matrix/delete/matrix_delete.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Prelude open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> let (a, _) = find_var "a" [] in diff --git a/tests/matrix/delete/matrix_delete_doc.ml b/tests/matrix/delete/matrix_delete_doc.ml index 0bba6d5f7..ac4ff14aa 100644 --- a/tests/matrix/delete/matrix_delete_doc.ml +++ b/tests/matrix/delete/matrix_delete_doc.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Prelude open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> let (a, _) = find_var "a" [] in diff --git a/tests/matrix/elim_mops/matrix_elim_mops.ml b/tests/matrix/elim_mops/matrix_elim_mops.ml index eeddf2957..80f256a00 100644 --- a/tests/matrix/elim_mops/matrix_elim_mops.ml +++ b/tests/matrix/elim_mops/matrix_elim_mops.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) (* TODO: let _ = Flags.recompute_resources_between_steps := true *) diff --git a/tests/matrix/local_name/matrix_local_name.ml b/tests/matrix/local_name/matrix_local_name.ml index 5bf38fafb..5ba6a9a0a 100644 --- a/tests/matrix/local_name/matrix_local_name.ml +++ b/tests/matrix/local_name/matrix_local_name.ml @@ -1,9 +1,10 @@ +(* Deprecated *) open Optitrust open Prelude open Target -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) let _ = Run.script_cpp (fun _ -> (* diff --git a/tests/matrix/local_name/matrix_local_name_doc.ml b/tests/matrix/local_name/matrix_local_name_doc.ml index d5b992c2b..aae6665cc 100644 --- a/tests/matrix/local_name/matrix_local_name_doc.ml +++ b/tests/matrix/local_name/matrix_local_name_doc.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Prelude open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> let (a, _) = find_var "a" [] in diff --git a/tests/matrix/local_name_tile/matrix_local_name_tile.ml b/tests/matrix/local_name_tile/matrix_local_name_tile.ml index 93cd4985c..74a67603a 100644 --- a/tests/matrix/local_name_tile/matrix_local_name_tile.ml +++ b/tests/matrix/local_name_tile/matrix_local_name_tile.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) let _ = Run.script_cpp (fun _ -> (* let range a b = (trm_int a, trm_int b) in *) !! Matrix.local_name_tile ~alloc_instr:[cVarDef "a"] ~var:"a" ~local_var:"y_local" diff --git a/tests/matrix/local_name_tile/matrix_local_name_tile_basic.ml b/tests/matrix/local_name_tile/matrix_local_name_tile_basic.ml index d0394c62d..abdc1391b 100644 --- a/tests/matrix/local_name_tile/matrix_local_name_tile_basic.ml +++ b/tests/matrix/local_name_tile/matrix_local_name_tile_basic.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) (* let _ = Flags.pretty_matrix_notation := true *) let _ = Run.script_cpp (fun _ -> diff --git a/tests/matrix/local_name_tile/matrix_local_name_tile_basic_doc.ml b/tests/matrix/local_name_tile/matrix_local_name_tile_basic_doc.ml index 99eea34f4..5092b76cf 100644 --- a/tests/matrix/local_name_tile/matrix_local_name_tile_basic_doc.ml +++ b/tests/matrix/local_name_tile/matrix_local_name_tile_basic_doc.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> !! Matrix_basic.local_name_tile diff --git a/tests/matrix/local_name_tile/matrix_local_name_tile_doc.ml b/tests/matrix/local_name_tile/matrix_local_name_tile_doc.ml index ac0545b1a..d9e73703d 100644 --- a/tests/matrix/local_name_tile/matrix_local_name_tile_doc.ml +++ b/tests/matrix/local_name_tile/matrix_local_name_tile_doc.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> !! Matrix.local_name_tile diff --git a/tests/matrix/reorder_dims/matrix_reorder_dims.ml b/tests/matrix/reorder_dims/matrix_reorder_dims.ml index db6c5ce2d..d1cb15cec 100644 --- a/tests/matrix/reorder_dims/matrix_reorder_dims.ml +++ b/tests/matrix/reorder_dims/matrix_reorder_dims.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Target open Trm let _ = - Flags.check_validity := true; + (* Flags.check_validity := true; *) Flags.detailed_resources_in_trace := true; Flags.save_ast_for_steps := Some Steps_all diff --git a/tests/matrix/stack_copy/matrix_stack_copy.ml b/tests/matrix/stack_copy/matrix_stack_copy.ml index ee493fc81..f0c4fa6e6 100644 --- a/tests/matrix/stack_copy/matrix_stack_copy.ml +++ b/tests/matrix/stack_copy/matrix_stack_copy.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) (* let _ = Flags.print_optitrust_syntax := true diff --git a/tests/matrix/stack_copy/matrix_stack_copy_doc.ml b/tests/matrix/stack_copy/matrix_stack_copy_doc.ml index 20b27ed09..071851a0e 100644 --- a/tests/matrix/stack_copy/matrix_stack_copy_doc.ml +++ b/tests/matrix/stack_copy/matrix_stack_copy_doc.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun () -> !! (); diff --git a/tests/perf/typing_big_perf.ml b/tests/perf/typing_big_perf.ml index 2003607d8..6010b71c4 100644 --- a/tests/perf/typing_big_perf.ml +++ b/tests/perf/typing_big_perf.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) let _ = Flags.report_exectime := true let _ = Run.script_cpp (fun () -> diff --git a/tests/perf/typing_perf.ml b/tests/perf/typing_perf.ml index ed4d6e3f7..ce4acb4c9 100644 --- a/tests/perf/typing_perf.ml +++ b/tests/perf/typing_perf.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) let _ = Flags.report_exectime := true diff --git a/tests/record/set_explicit/record_set_explicit_basic.ml b/tests/record/set_explicit/record_set_explicit_basic.ml index 06f926970..3be422fe3 100644 --- a/tests/record/set_explicit/record_set_explicit_basic.ml +++ b/tests/record/set_explicit/record_set_explicit_basic.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) let _ = Run.script_cpp ( fun _ -> !! Record_basic.set_explicit [sInstr "b = p"]; diff --git a/tests/record/set_explicit/record_set_explicit_basic_doc.ml b/tests/record/set_explicit/record_set_explicit_basic_doc.ml index 804e13dc4..269682931 100644 --- a/tests/record/set_explicit/record_set_explicit_basic_doc.ml +++ b/tests/record/set_explicit/record_set_explicit_basic_doc.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> diff --git a/tests/record/to_variables/record_to_variables.ml b/tests/record/to_variables/record_to_variables.ml index 25d15f63f..af10ae839 100644 --- a/tests/record/to_variables/record_to_variables.ml +++ b/tests/record/to_variables/record_to_variables.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) let _ = Run.script_cpp (fun _ -> !! Record_basic.to_variables [cVarDef "a"]; diff --git a/tests/resources/arbitrary_fracs/specialize_arbitrary_fracs.ml b/tests/resources/arbitrary_fracs/specialize_arbitrary_fracs.ml index da149bede..b90736963 100644 --- a/tests/resources/arbitrary_fracs/specialize_arbitrary_fracs.ml +++ b/tests/resources/arbitrary_fracs/specialize_arbitrary_fracs.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) let _ = Run.script_cpp (fun () -> !! Resources.specialize_arbitrary_fracs [cFunDef "one_fork"; cFor "j"; tBefore]; diff --git a/tests/resources/computation/aliases.ml b/tests/resources/computation/aliases.ml index 5f63d8e0b..b35779b7f 100644 --- a/tests/resources/computation/aliases.ml +++ b/tests/resources/computation/aliases.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) (*let _ = Flags.resource_errors_as_warnings := true*) let _ = Run.script_cpp (fun () -> ()) diff --git a/tests/resources/computation/alloc.ml b/tests/resources/computation/alloc.ml index 619728f75..e9237fecc 100644 --- a/tests/resources/computation/alloc.ml +++ b/tests/resources/computation/alloc.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) (*let _ = Flags.resource_errors_as_warnings := true*) let _ = Flags.save_ast_for_steps := Some Steps_all diff --git a/tests/resources/computation/array_write.ml b/tests/resources/computation/array_write.ml index 5f63d8e0b..b35779b7f 100644 --- a/tests/resources/computation/array_write.ml +++ b/tests/resources/computation/array_write.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) (*let _ = Flags.resource_errors_as_warnings := true*) let _ = Run.script_cpp (fun () -> ()) diff --git a/tests/resources/computation/call_lambda.ml b/tests/resources/computation/call_lambda.ml index 5f63d8e0b..b35779b7f 100644 --- a/tests/resources/computation/call_lambda.ml +++ b/tests/resources/computation/call_lambda.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) (*let _ = Flags.resource_errors_as_warnings := true*) let _ = Run.script_cpp (fun () -> ()) diff --git a/tests/resources/computation/fun_args.ml b/tests/resources/computation/fun_args.ml index e407a34f6..bea5224cb 100644 --- a/tests/resources/computation/fun_args.ml +++ b/tests/resources/computation/fun_args.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) (*let _ = Flags.resource_errors_as_warnings := true*) let _ = Run.script_cpp (fun () -> diff --git a/tests/resources/computation/ghost_args.ml b/tests/resources/computation/ghost_args.ml index 87d83aafb..fe71e5f25 100644 --- a/tests/resources/computation/ghost_args.ml +++ b/tests/resources/computation/ghost_args.ml @@ -1,6 +1,7 @@ +(* Deprecated *) open Optitrust -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) let _ = Run.script_cpp (fun () -> ()) diff --git a/tests/resources/computation/ghost_beta_reduce.ml b/tests/resources/computation/ghost_beta_reduce.ml index 5f63d8e0b..b35779b7f 100644 --- a/tests/resources/computation/ghost_beta_reduce.ml +++ b/tests/resources/computation/ghost_beta_reduce.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) (*let _ = Flags.resource_errors_as_warnings := true*) let _ = Run.script_cpp (fun () -> ()) diff --git a/tests/resources/computation/ghost_clear.ml b/tests/resources/computation/ghost_clear.ml index d48276f99..d0b780318 100644 --- a/tests/resources/computation/ghost_clear.ml +++ b/tests/resources/computation/ghost_clear.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) let _ = Run.script_cpp (fun () -> !! Trace.recompute_resources (); diff --git a/tests/resources/computation/if.ml b/tests/resources/computation/if.ml index d1b9916c4..b5ff0187f 100644 --- a/tests/resources/computation/if.ml +++ b/tests/resources/computation/if.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) let _ = Flags.detailed_resources_in_trace := true (*let _ = Flags.resource_errors_as_warnings := true*) diff --git a/tests/resources/computation/incr.ml b/tests/resources/computation/incr.ml index 5f63d8e0b..b35779b7f 100644 --- a/tests/resources/computation/incr.ml +++ b/tests/resources/computation/incr.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) (*let _ = Flags.resource_errors_as_warnings := true*) let _ = Run.script_cpp (fun () -> ()) diff --git a/tests/resources/computation/let_ghost.ml b/tests/resources/computation/let_ghost.ml index 046cccd6c..4c5f44a75 100644 --- a/tests/resources/computation/let_ghost.ml +++ b/tests/resources/computation/let_ghost.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) (*let _ = Flags.resource_errors_as_warnings := true*) let _ = Run.script_cpp (fun () -> ()) diff --git a/tests/resources/computation/loop_contracts.ml b/tests/resources/computation/loop_contracts.ml index a5acf9b60..9aafc58f0 100644 --- a/tests/resources/computation/loop_contracts.ml +++ b/tests/resources/computation/loop_contracts.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) (*let _ = Flags.resource_errors_as_warnings := true*) let _ = Run.script_cpp (fun () -> diff --git a/tests/resources/computation/make_strict_loop_contract.ml b/tests/resources/computation/make_strict_loop_contract.ml index 5f63d8e0b..b35779b7f 100644 --- a/tests/resources/computation/make_strict_loop_contract.ml +++ b/tests/resources/computation/make_strict_loop_contract.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) (*let _ = Flags.resource_errors_as_warnings := true*) let _ = Run.script_cpp (fun () -> ()) diff --git a/tests/resources/computation/matmul_strict_annot.ml b/tests/resources/computation/matmul_strict_annot.ml index 5f63d8e0b..b35779b7f 100644 --- a/tests/resources/computation/matmul_strict_annot.ml +++ b/tests/resources/computation/matmul_strict_annot.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) (*let _ = Flags.resource_errors_as_warnings := true*) let _ = Run.script_cpp (fun () -> ()) diff --git a/tests/resources/computation/matrix_alloc.ml b/tests/resources/computation/matrix_alloc.ml index 5f63d8e0b..b35779b7f 100644 --- a/tests/resources/computation/matrix_alloc.ml +++ b/tests/resources/computation/matrix_alloc.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) (*let _ = Flags.resource_errors_as_warnings := true*) let _ = Run.script_cpp (fun () -> ()) diff --git a/tests/resources/computation/matrix_copy.ml b/tests/resources/computation/matrix_copy.ml index 5f63d8e0b..b35779b7f 100644 --- a/tests/resources/computation/matrix_copy.ml +++ b/tests/resources/computation/matrix_copy.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) (*let _ = Flags.resource_errors_as_warnings := true*) let _ = Run.script_cpp (fun () -> ()) diff --git a/tests/resources/computation/mut_var.ml b/tests/resources/computation/mut_var.ml index 5f63d8e0b..b35779b7f 100644 --- a/tests/resources/computation/mut_var.ml +++ b/tests/resources/computation/mut_var.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) (*let _ = Flags.resource_errors_as_warnings := true*) let _ = Run.script_cpp (fun () -> ()) diff --git a/tests/resources/computation/normalize_access.ml b/tests/resources/computation/normalize_access.ml index 5f63d8e0b..b35779b7f 100644 --- a/tests/resources/computation/normalize_access.ml +++ b/tests/resources/computation/normalize_access.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) (*let _ = Flags.resource_errors_as_warnings := true*) let _ = Run.script_cpp (fun () -> ()) diff --git a/tests/resources/computation/optitrust_header.ml b/tests/resources/computation/optitrust_header.ml index c00cdd172..42e264ef0 100644 --- a/tests/resources/computation/optitrust_header.ml +++ b/tests/resources/computation/optitrust_header.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) (*let _ = Flags.debug_parsing_serialization := true*) (*let _ = Flags.resource_errors_as_warnings := true*) diff --git a/tests/resources/computation/read_only.ml b/tests/resources/computation/read_only.ml index 5f63d8e0b..b35779b7f 100644 --- a/tests/resources/computation/read_only.ml +++ b/tests/resources/computation/read_only.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) (*let _ = Flags.resource_errors_as_warnings := true*) let _ = Run.script_cpp (fun () -> ()) diff --git a/tests/resources/computation/simplify_fracs.ml b/tests/resources/computation/simplify_fracs.ml index a0cf0b558..3660d6c54 100644 --- a/tests/resources/computation/simplify_fracs.ml +++ b/tests/resources/computation/simplify_fracs.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) (*let _ = Flags.resource_errors_as_warnings := true*) let _ = Run.script_cpp (fun () -> ()) diff --git a/tests/resources/computation/uninit.ml b/tests/resources/computation/uninit.ml index a0cf0b558..3660d6c54 100644 --- a/tests/resources/computation/uninit.ml +++ b/tests/resources/computation/uninit.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) (*let _ = Flags.resource_errors_as_warnings := true*) let _ = Run.script_cpp (fun () -> ()) diff --git a/tests/resources/contracts/detach_loop_ro_focus.ml b/tests/resources/contracts/detach_loop_ro_focus.ml index a462cc8c7..c282bee28 100644 --- a/tests/resources/contracts/detach_loop_ro_focus.ml +++ b/tests/resources/contracts/detach_loop_ro_focus.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun () -> !! Resources.detach_loop_ro_focus [cFor "i"]; diff --git a/tests/resources/contracts/fix_types_in_contracts.ml b/tests/resources/contracts/fix_types_in_contracts.ml index 5f63d8e0b..b35779b7f 100644 --- a/tests/resources/contracts/fix_types_in_contracts.ml +++ b/tests/resources/contracts/fix_types_in_contracts.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) (*let _ = Flags.resource_errors_as_warnings := true*) let _ = Run.script_cpp (fun () -> ()) diff --git a/tests/resources/contracts/fun_minimize.ml b/tests/resources/contracts/fun_minimize.ml index 5b97f7c6f..1ee65ad26 100644 --- a/tests/resources/contracts/fun_minimize.ml +++ b/tests/resources/contracts/fun_minimize.ml @@ -1,10 +1,11 @@ +(* Deprecated *) open Optitrust open Target open Resources (*let _ = Flags.resource_errors_as_warnings := true*) -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) let _ = Run.script_cpp (fun () -> !! fun_minimize [cFunDef "unused_modifies"]; diff --git a/tests/resources/contracts/loop_minimize.ml b/tests/resources/contracts/loop_minimize.ml index 9e6effb73..822e06dd5 100644 --- a/tests/resources/contracts/loop_minimize.ml +++ b/tests/resources/contracts/loop_minimize.ml @@ -1,10 +1,11 @@ +(* Deprecated *) open Optitrust open Target open Resources (*let _ = Flags.resource_errors_as_warnings := true*) -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) let _ = Run.script_cpp (fun () -> !! loop_minimize [cFunBody "unused_modifies"; cFor "i"]; diff --git a/tests/resources/ghost/ghost_embed_loop.ml b/tests/resources/ghost/ghost_embed_loop.ml index 05f601def..ae9891b1a 100644 --- a/tests/resources/ghost/ghost_embed_loop.ml +++ b/tests/resources/ghost/ghost_embed_loop.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) let _ = Run.script_cpp (fun () -> !! Ghost.embed_loop [nbMulti; cFor "i"]; diff --git a/tests/resources/ghost_pair/ghost_pair_distribute.ml b/tests/resources/ghost_pair/ghost_pair_distribute.ml index 54f36f9ec..50b05f31f 100644 --- a/tests/resources/ghost_pair/ghost_pair_distribute.ml +++ b/tests/resources/ghost_pair/ghost_pair_distribute.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun () -> !! Ghost_pair.fission [tBefore; nbMulti; sInstr "+= 1"]; diff --git a/tests/resources/ghost_pair/ghost_pair_intro_elim.ml b/tests/resources/ghost_pair/ghost_pair_intro_elim.ml index c48ec4e6e..326ec64d3 100644 --- a/tests/resources/ghost_pair/ghost_pair_intro_elim.ml +++ b/tests/resources/ghost_pair/ghost_pair_intro_elim.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun () -> !! Ghost_pair.elim [cVarDef "focusA"]; diff --git a/tests/resources/ghost_pair/ghost_pair_intro_elim_lambda.ml b/tests/resources/ghost_pair/ghost_pair_intro_elim_lambda.ml index 4061cfc94..73de3ebde 100644 --- a/tests/resources/ghost_pair/ghost_pair_intro_elim_lambda.ml +++ b/tests/resources/ghost_pair/ghost_pair_intro_elim_lambda.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun () -> !! Ghost_pair.elim ~mark_begin:"b" ~mark_end:"e" [cVarDef "pair"]; diff --git a/tests/resources/ghost_pair/ghost_pair_minimize.ml b/tests/resources/ghost_pair/ghost_pair_minimize.ml index 518fe32e0..1c354e523 100644 --- a/tests/resources/ghost_pair/ghost_pair_minimize.ml +++ b/tests/resources/ghost_pair/ghost_pair_minimize.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) let _ = Run.script_cpp (fun () -> !! Ghost_pair.minimize_all_in_seq [cFunBody ""]; diff --git a/tests/resources/ghost_pair/move_in_loop.ml b/tests/resources/ghost_pair/move_in_loop.ml index 6b43b840e..0c1793422 100644 --- a/tests/resources/ghost_pair/move_in_loop.ml +++ b/tests/resources/ghost_pair/move_in_loop.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) let _ = Run.script_cpp (fun _ -> diff --git a/tests/resources/ghost_pure/ghost_pure_copy_surrounding_inside.ml b/tests/resources/ghost_pure/ghost_pure_copy_surrounding_inside.ml index 2e96ea674..f07dfa62b 100644 --- a/tests/resources/ghost_pure/ghost_pure_copy_surrounding_inside.ml +++ b/tests/resources/ghost_pure/ghost_pure_copy_surrounding_inside.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) let _ = Run.script_cpp (fun () -> !! Ghost_pure.copy_surrounding_inside [cFor "i"]; diff --git a/tests/resources/ghost_pure/ghost_pure_fission.ml b/tests/resources/ghost_pure/ghost_pure_fission.ml index a3e70455d..690ed1783 100644 --- a/tests/resources/ghost_pure/ghost_pure_fission.ml +++ b/tests/resources/ghost_pure/ghost_pure_fission.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) let _ = Run.script_cpp (fun () -> !! iteri (fun i p -> Marks.add (Printf.sprintf "m%d" i) (target_of_path p)) [cFunBody "f"; tBetweenAll]; diff --git a/tests/resources/ghost_pure/ghost_pure_minimize.ml b/tests/resources/ghost_pure/ghost_pure_minimize.ml index c6c8942fc..d82a001a4 100644 --- a/tests/resources/ghost_pure/ghost_pure_minimize.ml +++ b/tests/resources/ghost_pure/ghost_pure_minimize.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) let _ = Run.script_cpp (fun () -> !! Resources.ensure_computed (); diff --git a/tests/resources/ghost_pure/ghost_pure_move_all_upwards.ml b/tests/resources/ghost_pure/ghost_pure_move_all_upwards.ml index 0375f8f46..ff08db79a 100644 --- a/tests/resources/ghost_pure/ghost_pure_move_all_upwards.ml +++ b/tests/resources/ghost_pure/ghost_pure_move_all_upwards.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) let _ = Run.script_cpp (fun () -> !! iteri (fun i p -> Marks.add (Printf.sprintf "m%d" i) (target_of_path p)) [cFunBody "f"; tBetweenAll]; diff --git a/tests/resources/ghost_pure/ghost_pure_move_surrounding_inside.ml b/tests/resources/ghost_pure/ghost_pure_move_surrounding_inside.ml index fdd1947db..0b9a14b7b 100644 --- a/tests/resources/ghost_pure/ghost_pure_move_surrounding_inside.ml +++ b/tests/resources/ghost_pure/ghost_pure_move_surrounding_inside.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) let _ = Run.script_cpp (fun () -> !! Ghost_pure.minimize_all_in_seq [cFunBody "f"]; diff --git a/tests/resources_with_models/computation/optitrust_header.ml b/tests/resources_with_models/computation/optitrust_header.ml index 353ee736c..ffa0adc13 100644 --- a/tests/resources_with_models/computation/optitrust_header.ml +++ b/tests/resources_with_models/computation/optitrust_header.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) (*let _ = Flags.debug_parsing_serialization := true*) (*let _ = Flags.resource_errors_as_warnings := true*) diff --git a/tests/sequence/delete/sequence_delete.ml b/tests/sequence/delete/sequence_delete.ml index f270a7570..322e54ff8 100644 --- a/tests/sequence/delete/sequence_delete.ml +++ b/tests/sequence/delete/sequence_delete.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> (* TODO: add function calls. *) diff --git a/tests/sequence/elim/sequence_elim.ml b/tests/sequence/elim/sequence_elim.ml index 1ea79d1ac..ff5465dc3 100644 --- a/tests/sequence/elim/sequence_elim.ml +++ b/tests/sequence/elim/sequence_elim.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp ( fun _ -> diff --git a/tests/sequence/elim_instr/sequence_elim_instr.ml b/tests/sequence/elim_instr/sequence_elim_instr.ml index bda611693..5e6bf95aa 100644 --- a/tests/sequence/elim_instr/sequence_elim_instr.ml +++ b/tests/sequence/elim_instr/sequence_elim_instr.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp ( fun _ -> diff --git a/tests/sequence/elim_instr/sequence_elim_instr_doc.ml b/tests/sequence/elim_instr/sequence_elim_instr_doc.ml index 3eb2607bc..20651276d 100644 --- a/tests/sequence/elim_instr/sequence_elim_instr_doc.ml +++ b/tests/sequence/elim_instr/sequence_elim_instr_doc.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> diff --git a/tests/sequence/elim_let/sequence_elim_let.ml b/tests/sequence/elim_let/sequence_elim_let.ml index 5b41d376a..b51aa0104 100644 --- a/tests/sequence/elim_let/sequence_elim_let.ml +++ b/tests/sequence/elim_let/sequence_elim_let.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp ( fun _ -> !! Sequence_basic.elim_let [nbMulti; cVarDef ~body:[cStrictNew; cSeq ()] ""]; diff --git a/tests/sequence/intro/sequence_intro.ml b/tests/sequence/intro/sequence_intro.ml index 9ecd05ea0..1bf5b108c 100644 --- a/tests/sequence/intro/sequence_intro.ml +++ b/tests/sequence/intro/sequence_intro.ml @@ -1,3 +1,4 @@ +(* Deprecated *) open Optitrust open Target @@ -6,7 +7,7 @@ open Target takes a target and resolves it to several (consecutive!) items within a same sequence, then return the path to the sequence, a start position and a number of items. *) -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> !! Sequence.intro ~on:[cVarDef "a"] (); diff --git a/tests/sequence/intro/sequence_intro_basic.ml b/tests/sequence/intro/sequence_intro_basic.ml index a9518bfaa..cdeafec5d 100644 --- a/tests/sequence/intro/sequence_intro_basic.ml +++ b/tests/sequence/intro/sequence_intro_basic.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> diff --git a/tests/sequence/intro/sequence_intro_basic_doc.ml b/tests/sequence/intro/sequence_intro_basic_doc.ml index 4a372b25f..356456da9 100644 --- a/tests/sequence/intro/sequence_intro_basic_doc.ml +++ b/tests/sequence/intro/sequence_intro_basic_doc.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> diff --git a/tests/sequence/intro/sequence_intro_doc.ml b/tests/sequence/intro/sequence_intro_doc.ml index beed47c3d..261ef2936 100644 --- a/tests/sequence/intro/sequence_intro_doc.ml +++ b/tests/sequence/intro/sequence_intro_doc.ml @@ -1,3 +1,4 @@ +(* Deprecated *) open Optitrust open Target @@ -6,7 +7,7 @@ open Target takes a target and resolves it to several (consecutive!) items within a same sequence, then return the path to the sequence, a start position and a number of items. *) -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> !! Sequence.intro ~on:[cVarDef "a"] (); diff --git a/tests/sequence/split/sequence_split.ml b/tests/sequence/split/sequence_split.ml index b811a473a..9c5a09e46 100644 --- a/tests/sequence/split/sequence_split.ml +++ b/tests/sequence/split/sequence_split.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> diff --git a/tests/sequence/split/sequence_split_doc.ml b/tests/sequence/split/sequence_split_doc.ml index f66da6b24..d57ea1c3c 100644 --- a/tests/sequence/split/sequence_split_doc.ml +++ b/tests/sequence/split/sequence_split_doc.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> diff --git a/tests/stencil/fusion_targets/stencil_fusion_targets.ml b/tests/stencil/fusion_targets/stencil_fusion_targets.ml index 06dc9106e..6d0ba569b 100644 --- a/tests/stencil/fusion_targets/stencil_fusion_targets.ml +++ b/tests/stencil/fusion_targets/stencil_fusion_targets.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := false +(* let _ = Flags.check_validity := false *) let _ = Run.script_cpp ( fun _ -> (* !! Resources.ensure_computed (); *) diff --git a/tests/variable/elim_reuse/variable_elim_reuse.ml b/tests/variable/elim_reuse/variable_elim_reuse.ml index 6802fe412..50920fcfc 100644 --- a/tests/variable/elim_reuse/variable_elim_reuse.ml +++ b/tests/variable/elim_reuse/variable_elim_reuse.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> !! Variable.elim_reuse [cFunBody "f"; cVarDef "x"]; diff --git a/tests/variable/elim_reuse/variable_elim_reuse_doc.ml b/tests/variable/elim_reuse/variable_elim_reuse_doc.ml index 63b9cef58..ac8c3ddc4 100644 --- a/tests/variable/elim_reuse/variable_elim_reuse_doc.ml +++ b/tests/variable/elim_reuse/variable_elim_reuse_doc.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> !! Variable.elim_reuse [cVarDef "x"]; diff --git a/tests/variable/init_attach/variable_init_attach.ml b/tests/variable/init_attach/variable_init_attach.ml index 28b3d5840..838178857 100644 --- a/tests/variable/init_attach/variable_init_attach.ml +++ b/tests/variable/init_attach/variable_init_attach.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> !! Variable_basic.init_attach [cVarDef "x"]; diff --git a/tests/variable/init_detach/variable_init_detach.ml b/tests/variable/init_detach/variable_init_detach.ml index 3aff7415c..1bc17dbcf 100644 --- a/tests/variable/init_detach/variable_init_detach.ml +++ b/tests/variable/init_detach/variable_init_detach.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> diff --git a/tests/variable/init_detach/variable_init_detach_doc.ml b/tests/variable/init_detach/variable_init_detach_doc.ml index 5f3c34883..1b30fc08d 100644 --- a/tests/variable/init_detach/variable_init_detach_doc.ml +++ b/tests/variable/init_detach/variable_init_detach_doc.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> diff --git a/tests/variable/inline/variable_inline_basic.ml b/tests/variable/inline/variable_inline_basic.ml index cdd4f38b6..6c0941054 100644 --- a/tests/variable/inline/variable_inline_basic.ml +++ b/tests/variable/inline/variable_inline_basic.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> diff --git a/tests/variable/local_name/variable_local_name.ml b/tests/variable/local_name/variable_local_name.ml index 2139bb95e..0276c9a5d 100644 --- a/tests/variable/local_name/variable_local_name.ml +++ b/tests/variable/local_name/variable_local_name.ml @@ -1,7 +1,8 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) let _ = Run.script_cpp (fun _ -> !! Variable.local_name ~var:"a" ~local_var:"x" [cFunBody "ok1"; cFor "i"]; diff --git a/tests/variable/subst/variable_subst.ml b/tests/variable/subst/variable_subst.ml index 5af8330d5..35db5e376 100644 --- a/tests/variable/subst/variable_subst.ml +++ b/tests/variable/subst/variable_subst.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) let _ = Run.script_cpp (fun _ -> let x = trm_find_var "x" [] in diff --git a/tests/variable/subst/variable_subst_doc.ml b/tests/variable/subst/variable_subst_doc.ml index 79e99d34d..d88c0c104 100644 --- a/tests/variable/subst/variable_subst_doc.ml +++ b/tests/variable/subst/variable_subst_doc.ml @@ -1,8 +1,9 @@ +(* Deprecated *) open Optitrust open Prelude -let _ = Flags.check_validity := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.check_validity := true *) +(* let _ = Flags.recompute_resources_between_steps := true *) let _ = Run.script_cpp (fun _ -> let (a, _) = find_var "a" [] in From d725fd3839a9fccfd20db2f1e0eb89ea643310b5 Mon Sep 17 00:00:00 2001 From: "yanni.lefki" Date: Mon, 20 Jul 2026 17:03:47 +0200 Subject: [PATCH 13/23] more cleaning --- lib/transfo/accesses_basic.ml | 2 +- lib/transfo/function_core.ml | 3 +-- lib/transfo/loop_basic.ml | 10 +++++----- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/lib/transfo/accesses_basic.ml b/lib/transfo/accesses_basic.ml index 2ff1fcde2..517a49649 100644 --- a/lib/transfo/accesses_basic.ml +++ b/lib/transfo/accesses_basic.ml @@ -279,7 +279,7 @@ let%transfo transform (f_get : trm -> trm) (f_set : trm -> trm) Target.iter (fun p -> Target.apply_at_path (trm_subst_var v (trm_var ~typ v_tr)) p ) [nbAny; cMark f_body_mark; cMark mark_handled_resources]; - if not !Flags.preserve_specs_only + if (* not !Flags.preserve_specs_only *) Flags.annotated_and_verified () then Resources.ensure_computed_at p_seq; )); Trace.justif "all of the transformed gets and sets operate on resources found at the begining of the scope" diff --git a/lib/transfo/function_core.ml b/lib/transfo/function_core.ml index 42c2a977f..3fab3a35f 100644 --- a/lib/transfo/function_core.ml +++ b/lib/transfo/function_core.ml @@ -290,9 +290,8 @@ let uninline_on (fct_decl : trm) let f_def = trm_let_fun ~contract f_dsp typ_unit ret_targs ret_body in let f_call = trm_apps (trm_var f_dsp) ret_args in to_type_ret_t := Some [Trm f_def; Trm f_call]; - *) Trace.justif "uninlining pure expressions is always correct" - end; + end; *) [Trm (match body_ret with | None -> trm_apps ~typ:ret_typ (trm_var f) ret_args | Some rv -> trm_set (List.hd ret_args) diff --git a/lib/transfo/loop_basic.ml b/lib/transfo/loop_basic.ml index 62e71005a..497c258e7 100644 --- a/lib/transfo/loop_basic.ml +++ b/lib/transfo/loop_basic.ml @@ -96,8 +96,8 @@ let collapse_on (simpl_mark : mark) (index : string) let ghosts_before = add_collapse_ghost ghost_group_collapse ghost_ro_group_collapse cj.iter_contract.pre.linear in let ghosts_after = add_collapse_ghost ghost_group_uncollapse ghost_ro_group_uncollapse cj.iter_contract.post.linear in let contract = Resource_contract.loop_contract_subst subst cj in - let body2 = body - (* if !Flags.check_validity then + let body2 = + if (* !Flags.check_validity *) Flags.annotated () then let instrs, _ = trm_inv ~error:"expected seq" trm_seq_inv body in let open Resource_formula in let open Resource_trm in @@ -106,10 +106,10 @@ let collapse_on (simpl_mark : mark) (index : string) Mlist.push_front (assume (formula_in_range new_i (formula_loop_range ri))) in trm_seq ~annot:body.annot instrs2 - else *) + else body in let t2 = trm_for ~contract rk (trm_subst subst body2) in - (* if !Flags.check_validity then begin + if (* !Flags.check_validity *) Flags.annotated () then begin Resource_formula.(Resource_trm.(trm_seq_helper ~braces:false [ Trm (assume (formula_geq ~typ:typ_int ri.stop (trm_int 0))); Trm (assume (formula_geq ~typ:typ_int rj.stop (trm_int 0))); @@ -117,7 +117,7 @@ let collapse_on (simpl_mark : mark) (index : string) Trm t2; TrmList ghosts_after ])) - end else *) + end else t2 (** [collapse]: expects the target [tg] to point at a simple loop nest: From 971246fc4730288777c79dce56922f672f668dba Mon Sep 17 00:00:00 2001 From: "yanni.lefki" Date: Mon, 20 Jul 2026 17:23:44 +0200 Subject: [PATCH 14/23] done cleaning "check_validity" . [WIP] Deprecating non-model flags --- tests/accesses/shift/accesses_shift_models.ml | 3 ++- tests/arith/simpl/arith_simpl_models.ml | 3 ++- tests/debug/test_debug.ml | 3 ++- tests/gpu/thread_for_test.ml | 3 ++- tests/loop/hoist/loop_hoist_models.ml | 5 +++-- tests/loop/hoist_expr/loop_hoist_expr_models.ml | 3 ++- tests/loop/reorder_at/loop_reorder_at_models.ml | 3 ++- .../local_name_tile/matrix_local_name_tile_basic_models.ml | 3 ++- tests/reduce_models/reduce_models_slide.ml | 3 ++- tests/resources/contracts/loop_mode_check.ml | 3 ++- .../arbitrary_fracs/specialize_arbitrary_fracs.ml | 3 ++- tests/resources_with_models/computation/fun_args.ml | 3 ++- tests/resources_with_models/computation/ghost_beta_reduce.ml | 3 ++- tests/resources_with_models/computation/if.ml | 3 ++- tests/resources_with_models/computation/incr.ml | 3 ++- tests/resources_with_models/computation/matrix_alloc.ml | 3 ++- tests/resources_with_models/computation/matrix_copy.ml | 3 ++- tests/resources_with_models/computation/write0.ml | 3 ++- tests/template/template_basic.ml | 3 ++- tests/variable/inline/variable_inline_basic_models.ml | 3 ++- 20 files changed, 41 insertions(+), 21 deletions(-) diff --git a/tests/accesses/shift/accesses_shift_models.ml b/tests/accesses/shift/accesses_shift_models.ml index 06ac7c37c..b27ac50f7 100644 --- a/tests/accesses/shift/accesses_shift_models.ml +++ b/tests/accesses/shift/accesses_shift_models.ml @@ -1,7 +1,8 @@ open Optitrust open Prelude -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) +let _ = Flags.typechecking_mode := Flags.AnnotatedAndVerified let _ = Flags.recompute_resources_between_steps := true let _ = Flags.use_resources_with_models := true (* let _ = Flags.preserve_specs_only := true *) diff --git a/tests/arith/simpl/arith_simpl_models.ml b/tests/arith/simpl/arith_simpl_models.ml index ff9987f8c..596b55606 100644 --- a/tests/arith/simpl/arith_simpl_models.ml +++ b/tests/arith/simpl/arith_simpl_models.ml @@ -1,7 +1,8 @@ open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) +let _ = Flags.typechecking_mode := Flags.AnnotatedAndVerified let _ = Flags.recompute_resources_between_steps := true let _ = Flags. use_resources_with_models := true diff --git a/tests/debug/test_debug.ml b/tests/debug/test_debug.ml index 0aab59247..ee4a250dd 100644 --- a/tests/debug/test_debug.ml +++ b/tests/debug/test_debug.ml @@ -1,7 +1,8 @@ open Optitrust open Prelude -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) +let _ = Flags.typechecking_mode := Flags.AnnotatedAndVerified let _ = Flags.disable_stringreprs := true let _ = Run.script_cpp (fun () -> diff --git a/tests/gpu/thread_for_test.ml b/tests/gpu/thread_for_test.ml index 4a70be5b9..6a250e348 100644 --- a/tests/gpu/thread_for_test.ml +++ b/tests/gpu/thread_for_test.ml @@ -2,7 +2,8 @@ open Optitrust open Prelude open Target -let _ = Flags.check_validity := false +(* let _ = Flags.check_validity := false *) +let _ = Flags.typechecking_mode := Flags.Unverified let _ = Flags.pretty_matrix_notation := true let _ = Flags.recompute_resources_between_steps := false diff --git a/tests/loop/hoist/loop_hoist_models.ml b/tests/loop/hoist/loop_hoist_models.ml index 47b37f79d..6771a95cb 100644 --- a/tests/loop/hoist/loop_hoist_models.ml +++ b/tests/loop/hoist/loop_hoist_models.ml @@ -1,9 +1,10 @@ open Optitrust open Prelude -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) +let _ = Flags.typechecking_mode := Flags.AnnotatedAndVerified let _ = Flags.recompute_resources_between_steps := true -let _ = Flags.use_resources_with_models := true +(* let _ = Flags.use_resources_with_models := true *) let _ = Run.script_cpp (fun () -> !! Resources.ensure_computed (); diff --git a/tests/loop/hoist_expr/loop_hoist_expr_models.ml b/tests/loop/hoist_expr/loop_hoist_expr_models.ml index e753320e5..112efc06b 100644 --- a/tests/loop/hoist_expr/loop_hoist_expr_models.ml +++ b/tests/loop/hoist_expr/loop_hoist_expr_models.ml @@ -1,7 +1,8 @@ open Optitrust open Prelude -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) +let _ = Flags.typechecking_mode := Flags.AnnotatedAndVerified let _ = Flags.recompute_resources_between_steps := true let _ = Run.script_cpp (fun () -> diff --git a/tests/loop/reorder_at/loop_reorder_at_models.ml b/tests/loop/reorder_at/loop_reorder_at_models.ml index a90223147..84d5cb2a7 100644 --- a/tests/loop/reorder_at/loop_reorder_at_models.ml +++ b/tests/loop/reorder_at/loop_reorder_at_models.ml @@ -2,7 +2,8 @@ open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) +let _ = Flags.typechecking_mode := Flags.AnnotatedAndVerified let _ = Flags.recompute_resources_between_steps := true let _ = Run.script_cpp (fun _ -> diff --git a/tests/matrix/local_name_tile/matrix_local_name_tile_basic_models.ml b/tests/matrix/local_name_tile/matrix_local_name_tile_basic_models.ml index dc81ace83..af94eb02e 100644 --- a/tests/matrix/local_name_tile/matrix_local_name_tile_basic_models.ml +++ b/tests/matrix/local_name_tile/matrix_local_name_tile_basic_models.ml @@ -1,7 +1,8 @@ open Optitrust open Prelude -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) +let _ = Flags.typechecking_mode := Flags.AnnotatedAndVerified let _ = Flags.recompute_resources_between_steps := true let _ = Flags.use_resources_with_models := true diff --git a/tests/reduce_models/reduce_models_slide.ml b/tests/reduce_models/reduce_models_slide.ml index 563810506..143f4a734 100644 --- a/tests/reduce_models/reduce_models_slide.ml +++ b/tests/reduce_models/reduce_models_slide.ml @@ -1,7 +1,8 @@ open Optitrust open Prelude -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) +let _ = Flags.typechecking_mode := Flags.AnnotatedAndVerified let _ = Flags.recompute_resources_between_steps := true let _ = Run.script_cpp(fun _ -> diff --git a/tests/resources/contracts/loop_mode_check.ml b/tests/resources/contracts/loop_mode_check.ml index d67079184..061b0907d 100644 --- a/tests/resources/contracts/loop_mode_check.ml +++ b/tests/resources/contracts/loop_mode_check.ml @@ -1,7 +1,8 @@ open Optitrust open Prelude -let _ = Flags.check_validity := false +(* let _ = Flags.check_validity := false *) +let _ = Flags.typechecking_mode := Flags.Unverified let _ = Flags.recompute_resources_between_steps := false let _ = Run.script_cpp (fun () -> diff --git a/tests/resources_with_models/arbitrary_fracs/specialize_arbitrary_fracs.ml b/tests/resources_with_models/arbitrary_fracs/specialize_arbitrary_fracs.ml index b5afff48d..dc9fdcbb8 100644 --- a/tests/resources_with_models/arbitrary_fracs/specialize_arbitrary_fracs.ml +++ b/tests/resources_with_models/arbitrary_fracs/specialize_arbitrary_fracs.ml @@ -1,7 +1,8 @@ open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) +let _ = Flags.typechecking_mode := Flags.AnnotatedAndVerified let _ = Flags.recompute_resources_between_steps := true let _ = Run.script_cpp (fun () -> diff --git a/tests/resources_with_models/computation/fun_args.ml b/tests/resources_with_models/computation/fun_args.ml index e407a34f6..446d8d5c5 100644 --- a/tests/resources_with_models/computation/fun_args.ml +++ b/tests/resources_with_models/computation/fun_args.ml @@ -1,7 +1,8 @@ open Optitrust open Prelude -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) +let _ = Flags.typechecking_mode := Flags.AnnotatedAndVerified let _ = Flags.recompute_resources_between_steps := true (*let _ = Flags.resource_errors_as_warnings := true*) diff --git a/tests/resources_with_models/computation/ghost_beta_reduce.ml b/tests/resources_with_models/computation/ghost_beta_reduce.ml index 5f63d8e0b..68564f282 100644 --- a/tests/resources_with_models/computation/ghost_beta_reduce.ml +++ b/tests/resources_with_models/computation/ghost_beta_reduce.ml @@ -1,6 +1,7 @@ open Optitrust -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) +let _ = Flags.typechecking_mode := Flags.AnnotatedAndVerified let _ = Flags.recompute_resources_between_steps := true (*let _ = Flags.resource_errors_as_warnings := true*) diff --git a/tests/resources_with_models/computation/if.ml b/tests/resources_with_models/computation/if.ml index d1b9916c4..fb818e9a0 100644 --- a/tests/resources_with_models/computation/if.ml +++ b/tests/resources_with_models/computation/if.ml @@ -1,6 +1,7 @@ open Optitrust -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) +let _ = Flags.typechecking_mode := Flags.AnnotatedAndVerified let _ = Flags.recompute_resources_between_steps := true let _ = Flags.detailed_resources_in_trace := true (*let _ = Flags.resource_errors_as_warnings := true*) diff --git a/tests/resources_with_models/computation/incr.ml b/tests/resources_with_models/computation/incr.ml index 5f63d8e0b..68564f282 100644 --- a/tests/resources_with_models/computation/incr.ml +++ b/tests/resources_with_models/computation/incr.ml @@ -1,6 +1,7 @@ open Optitrust -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) +let _ = Flags.typechecking_mode := Flags.AnnotatedAndVerified let _ = Flags.recompute_resources_between_steps := true (*let _ = Flags.resource_errors_as_warnings := true*) diff --git a/tests/resources_with_models/computation/matrix_alloc.ml b/tests/resources_with_models/computation/matrix_alloc.ml index 5f63d8e0b..68564f282 100644 --- a/tests/resources_with_models/computation/matrix_alloc.ml +++ b/tests/resources_with_models/computation/matrix_alloc.ml @@ -1,6 +1,7 @@ open Optitrust -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) +let _ = Flags.typechecking_mode := Flags.AnnotatedAndVerified let _ = Flags.recompute_resources_between_steps := true (*let _ = Flags.resource_errors_as_warnings := true*) diff --git a/tests/resources_with_models/computation/matrix_copy.ml b/tests/resources_with_models/computation/matrix_copy.ml index 5f63d8e0b..68564f282 100644 --- a/tests/resources_with_models/computation/matrix_copy.ml +++ b/tests/resources_with_models/computation/matrix_copy.ml @@ -1,6 +1,7 @@ open Optitrust -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) +let _ = Flags.typechecking_mode := Flags.AnnotatedAndVerified let _ = Flags.recompute_resources_between_steps := true (*let _ = Flags.resource_errors_as_warnings := true*) diff --git a/tests/resources_with_models/computation/write0.ml b/tests/resources_with_models/computation/write0.ml index 5f63d8e0b..68564f282 100644 --- a/tests/resources_with_models/computation/write0.ml +++ b/tests/resources_with_models/computation/write0.ml @@ -1,6 +1,7 @@ open Optitrust -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) +let _ = Flags.typechecking_mode := Flags.AnnotatedAndVerified let _ = Flags.recompute_resources_between_steps := true (*let _ = Flags.resource_errors_as_warnings := true*) diff --git a/tests/template/template_basic.ml b/tests/template/template_basic.ml index 92f36491c..e9f2db5b0 100644 --- a/tests/template/template_basic.ml +++ b/tests/template/template_basic.ml @@ -1,7 +1,8 @@ open Optitrust open Prelude -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) +let _ = Flags.typechecking_mode := Flags.AnnotatedAndVerified let _ = Flags.recompute_resources_between_steps := true let _ = Run.script_cpp (fun () -> ()); diff --git a/tests/variable/inline/variable_inline_basic_models.ml b/tests/variable/inline/variable_inline_basic_models.ml index ea51c3f18..8fd99acc4 100644 --- a/tests/variable/inline/variable_inline_basic_models.ml +++ b/tests/variable/inline/variable_inline_basic_models.ml @@ -1,7 +1,8 @@ open Optitrust open Target -let _ = Flags.check_validity := true +(* let _ = Flags.check_validity := true *) +let _ = Flags.typechecking_mode := Flags.AnnotatedAndVerified let _ = Flags.use_resources_with_models := true let _ = Run.script_cpp (fun _ -> From 06f0f65142a5909762d781565268e7b6ea286a67 Mon Sep 17 00:00:00 2001 From: "yanni.lefki" Date: Tue, 21 Jul 2026 17:14:00 +0200 Subject: [PATCH 15/23] wip cleaning flags --- lib/transfo/accesses_basic.ml | 59 ++----------------- lib/transfo/instr.ml | 32 +++++----- tests/accesses/shift/accesses_shift_models.ml | 6 +- 3 files changed, 23 insertions(+), 74 deletions(-) diff --git a/lib/transfo/accesses_basic.ml b/lib/transfo/accesses_basic.ml index 517a49649..5b681a14b 100644 --- a/lib/transfo/accesses_basic.ml +++ b/lib/transfo/accesses_basic.ml @@ -1,6 +1,10 @@ open Prelude open Target +(* DEBUG flags *) + +let debug_transform = true + type transform_ret = { typedvar : (var * typ option) option ref; matched_pre : formula list ref; @@ -230,60 +234,7 @@ let%transfo transform (f_get : trm -> trm) (f_set : trm -> trm) pure_post = ref []; } in Target.apply_at_path (transform_on f_get f_set f_cancel to_prove address_pattern mark_to_prove mark_preprocess mark_postprocess mark_handled_resources ret span) p_seq; - if (* !Flags.check_validity && not !Flags.preserve_specs_only *) Flags.annotated_and_verified () then begin - (* TODO: factorize with local_name, should this be a Resource.assert_??? feature? may also be decomposed via elim_reuse? *) - let error = "did not find on which inner pointer variable addresses where based" in - let (v, ty_opt) = Option.unsome ~error !(ret.typedvar) in - let typ = Option.unsome ~error ty_opt in - Trace.without_resource_computation_between_steps (fun () -> - let f_body_mark = next_mark () in - step_backtrack ~discard_after:true (fun () -> - let f = new_var "isolate_addr" in - let v_tr = new_var (v.name ^ "_tr") in - Target.apply_at_path (fun t_seq -> - let resolve_at tg = - let idxs = Target.resolve_target_between_children tg t_seq in - match idxs with - | [i] -> i - | _ -> failwith "expected a single index" - in - let span: Dir.span = { - start = resolve_at [cMarkSpanStop mark_preprocess]; - stop = resolve_at [cMarkSpanStart mark_postprocess]; - } in - let formulas_to_res = List.map (fun r -> Resource_formula.new_anon_hyp (), r) in - (* let linear_original res = formulas_to_res ( - (Resource_formula.formula_cell_var ~typ v_tr) :: res - ) in *) - let isolated_linear res = formulas_to_res ( - List.map (trm_subst_var v (trm_var ~typ v_tr)) res - ) in - update_span_helper span t_seq (fun instrs -> - let isolated_pre = isolated_linear !(ret.matched_pre) in - let isolated_post = isolated_linear !(ret.matched_post) in - let others_pre = formulas_to_res !(ret.others_pre) in - let others_post = formulas_to_res !(ret.others_post) in - let pre = Resource_set.make ~pure:(List.filter (fun (h, f) -> f = Resource_formula.typ_frac) !(ret.pure_pre)) ~linear:(isolated_pre @ others_pre) () in - (* TODO: Add ensured linear vars to post.pure *) - let post = Resource_set.make (*~pure:(List.filter (fun (h, f) -> f <> Resource_formula.typ_frac) !(ret.pure_post))*) ~linear:(isolated_post @ others_post) () in - let post = { post with linear = snd (Resource_computation.delete_stack_allocs (Mlist.to_list instrs) post) } in - let contract = FunSpecContract { pre; post } in - let f_body = trm_add_mark f_body_mark (trm_copy (trm_seq instrs)) in - let f_def = trm_let_fun ~contract f typ_unit [(v_tr, typ)] f_body in - (* TODO: instead of duplicating code, call f, but deactivate stack deallocation in the body of f ? *) - (* let f_call = trm_apps (trm_var f) [trm_var v] in *) - [Trm f_def; (* Trm f_call; *) TrmMlist instrs] - ) - ) p_seq; - (* DEBUG: Show.(trm ~style:(internal ~print_var_id:false ()) (get_trm_at_exn (target_of_path p_seq))); *) - Target.iter (fun p -> - Target.apply_at_path (trm_subst_var v (trm_var ~typ v_tr)) p - ) [nbAny; cMark f_body_mark; cMark mark_handled_resources]; - if (* not !Flags.preserve_specs_only *) Flags.annotated_and_verified () - then Resources.ensure_computed_at p_seq; - )); - Trace.justif "all of the transformed gets and sets operate on resources found at the begining of the scope" - end; + if debug_transform then Show.trm ~style:(Style.optilambda ()) ~msg:"term at p_seq" (resolve_path p_seq); ) tg) (** *) diff --git a/lib/transfo/instr.ml b/lib/transfo/instr.ml index 61c826c13..dafc4c609 100644 --- a/lib/transfo/instr.ml +++ b/lib/transfo/instr.ml @@ -264,23 +264,21 @@ let%transfo gather_targets ?(dest : gather_dest = GatherAtLast) (tg : target) : *) let%transfo move ~(dest : target) (tg : target) : unit = Trace.tag_atomic (); - (* if !Flags.check_validity then - (* TODO: handle move out of loop, conditions, etc. *) - Target.iter (fun p -> - let seq_path, span = Path.extract_last_dir_span p in - let dest_path, i = Target.resolve_target_between_exactly_one dest in - if seq_path <> dest_path then - path_fail dest_path "Instr.move: Unsupported move outside the sequence when checking validity"; - move_in_seq ~dest:[dBefore i] (target_of_path p) - ) tg - else *) - begin - Target.iter (fun p -> - let tg_trm = Target.resolve_path p in - Marks.add "instr_move_out" (target_of_path p); - Sequence_basic.insert tg_trm dest; - Instr_basic.delete [cMark "instr_move_out"]) tg - end + (* TODO: handle move out of loop, conditions, etc. *) + Target.iter (fun p -> + let seq_path, span = Path.extract_last_dir_span p in + let dest_path, i = Target.resolve_target_between_exactly_one dest in + if seq_path <> dest_path then + path_fail dest_path "Instr.move: Unsupported move outside the sequence when checking validity"; + move_in_seq ~dest:[dBefore i] (target_of_path p) + ) tg + (* DEPRECATED : can not handle empty spans *) + (* Target.iter (fun p -> + let tg_trm = Target.resolve_path p in + Marks.add "instr_move_out" (target_of_path p); + Sequence_basic.insert tg_trm dest; + Instr_basic.delete [cMark "instr_move_out"]) tg *) + (** [move_out tg]: moves the instruction targeted by [tg], just before its surrounding sequence. *) let%transfo move_out (tg : target) : unit = diff --git a/tests/accesses/shift/accesses_shift_models.ml b/tests/accesses/shift/accesses_shift_models.ml index b27ac50f7..1b441ed2d 100644 --- a/tests/accesses/shift/accesses_shift_models.ml +++ b/tests/accesses/shift/accesses_shift_models.ml @@ -7,9 +7,9 @@ let _ = Flags.recompute_resources_between_steps := true let _ = Flags.use_resources_with_models := true (* let _ = Flags.preserve_specs_only := true *) -let _ = Run.script_cpp (fun _ -> () - (* !! Resources.ensure_computed (); +let _ = Run.script_cpp (fun _ -> (* () + !! Resources.ensure_computed (); *) (* FIXME: support double, etc, 5.0 *) !! Accesses.shift_var ~factor:(trm_int 5) [nbMulti; cTopFunDef "test_var"; cVarDef "x"]; - !! Accesses.shift_var ~factor:(trm_int 1) [nbMulti; cTopFunDef "test_var_inv"; cVarDef "s"]; *) + (* !! Accesses.shift_var ~factor:(trm_int 1) [nbMulti; cTopFunDef "test_var_inv"; cVarDef "s"]; *) ) From ec6c3db3b05f41f9c079ba17a1d30ab6a2018870 Mon Sep 17 00:00:00 2001 From: "yanni.lefki" Date: Tue, 21 Jul 2026 17:43:51 +0200 Subject: [PATCH 16/23] solved one unit test --- tests/accesses/shift/accesses_shift_models.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/accesses/shift/accesses_shift_models.ml b/tests/accesses/shift/accesses_shift_models.ml index 1b441ed2d..2a19b0782 100644 --- a/tests/accesses/shift/accesses_shift_models.ml +++ b/tests/accesses/shift/accesses_shift_models.ml @@ -11,5 +11,5 @@ let _ = Run.script_cpp (fun _ -> (* () !! Resources.ensure_computed (); *) (* FIXME: support double, etc, 5.0 *) !! Accesses.shift_var ~factor:(trm_int 5) [nbMulti; cTopFunDef "test_var"; cVarDef "x"]; - (* !! Accesses.shift_var ~factor:(trm_int 1) [nbMulti; cTopFunDef "test_var_inv"; cVarDef "s"]; *) + !! Accesses.shift_var ~factor:(trm_int 1) [nbMulti; cTopFunDef "test_var_inv"; cVarDef "s"]; ) From 21c43f70fd3c016d4d457f135b89de48ee22d119 Mon Sep 17 00:00:00 2001 From: "yanni.lefki" Date: Wed, 22 Jul 2026 11:55:28 +0200 Subject: [PATCH 17/23] corrected weird comments coloring --- lib/transfo/loop.ml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/transfo/loop.ml b/lib/transfo/loop.ml index cabab6904..4684668f2 100644 --- a/lib/transfo/loop.ml +++ b/lib/transfo/loop.ml @@ -925,8 +925,8 @@ DETAILS for [unroll] where p points to the item "body(i+k)" {[ - ( if body(i) is instr1 instr2 instr3 instr4 instr5 - ( then i make { { instr1 instr2 } { instr3 instr4 instr5 } } + ( if body(i) is instr1 instr2 instr3 instr4 instr5 ) + ( then i make { { instr1 instr2 } { instr3 instr4 instr5 } } ) ]} {[ @@ -943,7 +943,7 @@ DETAILS for [unroll] { instr3 instr4 instr5(i+1) } { instr3 instr4 instr5(i+2) } }@? } - }] + ]} FOURTH SUBSTEP: remove nobrace sequences ===================note @@ -966,7 +966,8 @@ DETAILS for [unroll] cmd3(i+2) }]} - LATER: This transformation should be factorized, that may change the docs. *) + LATER: This transformation should be factorized, that may change the docs. +*) let%transfo unroll_one ?(inner_braces : bool = false) ?(outer_seq_with_mark : mark = no_mark) ?(simpl: target -> unit = default_simpl) (tg : target) : unit = Target.iteri (fun i p -> From 39e0016dceb4d9a49aaf3b4c6c4d4a5a38131c3e Mon Sep 17 00:00:00 2001 From: "yanni.lefki" Date: Wed, 22 Jul 2026 15:33:53 +0200 Subject: [PATCH 18/23] corrected loop reorder_at_models test. --- lib/framework/resources.ml | 6 +- lib/transfo/variable_basic.ml | 100 ++++++++++++++++------------------ 2 files changed, 50 insertions(+), 56 deletions(-) diff --git a/lib/framework/resources.ml b/lib/framework/resources.ml index 565645ea4..cce9fecae 100644 --- a/lib/framework/resources.ml +++ b/lib/framework/resources.ml @@ -9,13 +9,11 @@ let ensure_computed = Trace.recompute_resources TODO: required_for_check_at path; for on-demand computation. *) let required_for_check () : unit = (* Yanni : should require the AnnotatedAndVerified typechecking mode *) - (* if !Flags.check_validity && not !Flags.preserve_specs_only - then *) - ensure_computed () + if Flags.annotated_and_verified () then ensure_computed () let justif_correct (why : string) : unit = (* if !Flags.check_validity then begin *) - ensure_computed (); + if Flags.annotated () then ensure_computed (); Trace.justif (sprintf "resources are correct: %s" why) diff --git a/lib/transfo/variable_basic.ml b/lib/transfo/variable_basic.ml index ccbc76fc8..164bc062d 100644 --- a/lib/transfo/variable_basic.ml +++ b/lib/transfo/variable_basic.ml @@ -40,7 +40,7 @@ let%transfo unfold ?(mark : mark = no_mark) ~(at : target) (tg : target) : unit *) let%transfo inline ?(delete_decl : bool = true) ?(mark : mark = no_mark) (tg : target) : unit = (* if !Flags.check_validity then Scope.infer_var_ids (); (* FIXME: This should be done by previous transfo instead *) *) - if !Flags.use_resources_with_models then Resources.ensure_computed (); + (* if !Flags.use_resources_with_models then Resources.ensure_computed (); *) Target.iter (fun p -> let (p_seq, p_local, index) = Internal.get_instruction_in_surrounding_sequence p in assert (p_local = []); @@ -49,6 +49,8 @@ let%transfo inline ?(delete_decl : bool = true) ?(mark : mark = no_mark) (tg : t let tl, result = trm_inv ~error trm_seq_inv t_seq in let dl = Mlist.nth tl index in let x, _, init = trm_inv ~error:"expected a target to a variable definition" trm_let_inv dl in + + if Flags.annotated () then begin let init = trm_add_mark mark init in let res = Resources.after_trm init in let init_model = trm_add_mark mark (Var_map.find Resource_set.var_result res.aliases) in @@ -77,61 +79,55 @@ let%transfo inline ?(delete_decl : bool = true) ?(mark : mark = no_mark) (tg : t ] in let new_tl = Mlist.update_at_index_and_fix_beyond ~delete:delete_decl index (fun t -> t) perform_subst_trm tl in trm_seq ~annot:t_seq.annot ?result new_tl - (* LEGACY: shapes *) - (* Deprecated, legacy code *) - (* - end else begin - if !Flags.check_validity then begin - if Resources.trm_is_pure init then - (* Case 1: pure expression *) - Trace.justif "inlining a pure expression is always correct" - else begin - (* Case 2: duplicable expression can be inlined if we don't go through interfering context, control flow or formulas *) - Resources.required_for_check (); - (* Resources.assert_instr_effects_shadowed p; *) - (* -- DUPLICATE CODE *) - let t_seq = Target.resolve_path p_seq in - let tl, _ = trm_inv ~error trm_seq_inv t_seq in - let dl = Mlist.nth tl index in - let x, _, init = trm_inv ~error:"expected a target to a variable definition" trm_let_inv dl in - (* -- *) - Resources.assert_not_self_interfering init; - let occurences = Constr.resolve_target ~prefix:p_seq [nbMulti; cVarId x] t_seq in - let end_occ_index = match snd (List.unlast occurences) with - | Dir_seq_nth i :: _ -> i - | p -> path_fail p "expected path to be inside current sequence" - in - (* check that we don't go through control flow or formulas *) - List.iter (fun occ_p -> - List.iter (fun dir -> - let open Dir in - match dir with - | Dir_body | Dir_then | Dir_else - | Dir_for_start | Dir_for_stop | Dir_for_step - | Dir_for_c_init | Dir_for_c_step | Dir_case _ - | Dir_contract _ | Dir_ghost_arg_nth _ -> - path_fail (p_seq @ occ_p) (sprintf "inlining non-pure expression does not support going through %s yet" (Dir.dir_to_string dir)) - | _ -> () - ) occ_p - ) (List.drop 1 occurences); - (* is calling this useful? - Resources.assert_dup_instr_redundant index last_occ_index t_seq; *) - let usage = Resources.usage_of_trm init in - let _, instrs_after_let = Mlist.split (index + 1) tl in - let context_instrs, _ = Mlist.split (end_occ_index - index - 1) instrs_after_let in - (* DEBUG: Show.trms ~msg:"\n---- HERE:\n" (Mlist.to_list context_instrs); *) - let context_usage = Resources.compute_usage_of_instrs context_instrs in - (* TODO: double check that we don't need to check commute for every occ and not just last one. *) - Resources.assert_usages_commute ~res_ctx:(Resources.after_trm init) [path_error_context p] usage context_usage; - Trace.justif "inlining a duplicable expression through a non-interfering, non-control-flow and non-formula context is correct" - (* TODO: Case 3 ? recursive traversal analysis with special constructor cases? *) - (* trm_fail init "inlining non-pure expression is not yet supported, requires checking for interference similar to instr.swap, loop.move_out, etc" *) - end + end else + begin + if Flags.annotated () then + begin + (* Case 2: duplicable expression can be inlined if we don't go through interfering context, control flow or formulas *) + Resources.required_for_check (); + (* Resources.assert_instr_effects_shadowed p; *) + (* -- DUPLICATE CODE *) + let t_seq = Target.resolve_path p_seq in + let tl, _ = trm_inv ~error trm_seq_inv t_seq in + let dl = Mlist.nth tl index in + let x, _, init = trm_inv ~error:"expected a target to a variable definition" trm_let_inv dl in + (* -- *) + Resources.assert_not_self_interfering init; + let occurences = Constr.resolve_target ~prefix:p_seq [nbMulti; cVarId x] t_seq in + let end_occ_index = match snd (List.unlast occurences) with + | Dir_seq_nth i :: _ -> i + | p -> path_fail p "expected path to be inside current sequence" + in + (* check that we don't go through control flow or formulas *) + List.iter (fun occ_p -> + List.iter (fun dir -> + let open Dir in + match dir with + | Dir_body | Dir_then | Dir_else + | Dir_for_start | Dir_for_stop | Dir_for_step + | Dir_for_c_init | Dir_for_c_step | Dir_case _ + | Dir_contract _ | Dir_ghost_arg_nth _ -> + path_fail (p_seq @ occ_p) (sprintf "inlining non-pure expression does not support going through %s yet" (Dir.dir_to_string dir)) + | _ -> () + ) occ_p + ) (List.drop 1 occurences); + (* is calling this useful? + Resources.assert_dup_instr_redundant index last_occ_index t_seq; *) + let usage = Resources.usage_of_trm init in + let _, instrs_after_let = Mlist.split (index + 1) tl in + let context_instrs, _ = Mlist.split (end_occ_index - index - 1) instrs_after_let in + (* DEBUG: Show.trms ~msg:"\n---- HERE:\n" (Mlist.to_list context_instrs); *) + let context_usage = Resources.compute_usage_of_instrs context_instrs in + (* TODO: double check that we don't need to check commute for every occ and not just last one. *) + Resources.assert_usages_commute ~res_ctx:(Resources.after_trm init) [path_error_context p] usage context_usage; + Trace.justif "inlining a duplicable expression through a non-interfering, non-control-flow and non-formula context is correct" + (* TODO: Case 3 ? recursive traversal analysis with special constructor cases? *) + (* trm_fail init "inlining non-pure expression is not yet supported, requires checking for interference similar to instr.swap, loop.move_out, etc" *) end; let init = trm_add_mark mark init in let new_tl = Mlist.update_at_index_and_fix_beyond ~delete:delete_decl index (fun t -> t) (trm_subst_var x init) tl in trm_seq ~annot:t_seq.annot ?result new_tl - end *) + end ) p_seq ) tg From 63f8dadf3cffd033c9183df2d8f4bd127f9baa75 Mon Sep 17 00:00:00 2001 From: "yanni.lefki" Date: Thu, 23 Jul 2026 15:32:25 +0200 Subject: [PATCH 19/23] moving deprecated tests to ignored.tests --- case_studies/gpu/vector_add/vector_add.ml | 2 +- lib/framework/flags.ml | 2 +- lib/framework/runtime/trace.ml | 2 +- tests/ignore.tests | 98 +++++++++++++++++++ .../local_name/variable_local_name.ml | 24 +++-- .../local_name/variable_local_name_exp.cpp | 12 ++- .../variable/unfold/variable_unfold_basic.ml | 1 + 7 files changed, 121 insertions(+), 20 deletions(-) diff --git a/case_studies/gpu/vector_add/vector_add.ml b/case_studies/gpu/vector_add/vector_add.ml index 6eff6b333..1e71e5f69 100644 --- a/case_studies/gpu/vector_add/vector_add.ml +++ b/case_studies/gpu/vector_add/vector_add.ml @@ -25,7 +25,7 @@ let _ = Run.script_cpp (fun () -> !! Resources.ensure_computed (); (* Stage 2: create thread hierarchy *) - !! Gpu.convert_tail_thread_for [cFor "i"]; + !! Gpu.convert_tail_thread_for [] [cFor "i"]; !! Resources.ensure_computed (); (* Stage 3: convert memories *) diff --git a/lib/framework/flags.ml b/lib/framework/flags.ml index 9079266d0..0f470f8ee 100644 --- a/lib/framework/flags.ml +++ b/lib/framework/flags.ml @@ -78,7 +78,7 @@ let reparse_at_big_steps : bool ref = ref false let report_big_steps : bool ref = ref false (** [use_clang_format]: flag to use clang-format or not in output CPP files. *) -let use_clang_format : bool ref = ref true +let use_clang_format : bool ref = ref false (** [keep_file_before_clang_format]: flag to save the file before cleaning up with clang format "foo_out.cpp" is saved as "foo_out_notfmt.cpp". Used by the tester for faster correctness checks. *) diff --git a/lib/framework/runtime/trace.ml b/lib/framework/runtime/trace.ml index 791c49f08..1f96de43a 100644 --- a/lib/framework/runtime/trace.ml +++ b/lib/framework/runtime/trace.ml @@ -1435,7 +1435,7 @@ let failure_expected (h : exn -> bool) (f : unit -> unit) : unit = let resource_error_expected (f: unit -> unit): unit = failure_expected (function | Resource_computation.ResourceError _ -> true - | _ -> false) f + | _ -> false) (fun () -> f (); recompute_resources ()) (** [apply f]: applies the transformation [f] to the current AST, and updates the current ast with the result of that transformation. diff --git a/tests/ignore.tests b/tests/ignore.tests index e9b6f4d3d..8a26a11eb 100644 --- a/tests/ignore.tests +++ b/tests/ignore.tests @@ -4,6 +4,104 @@ debug perf interact +# BROKEN AFTER FLAGS CHANGE - TO FIX/DELETE +## wrong +resources/ghost_pure/ghost_pure_move_surrounding_inside.ml +resources/ghost_pure/ghost_pure_minimize.ml +resources/ghost_pair/move_in_loop.ml +resources/contracts/fun_minimize.ml +resources/computation/optitrust_header.ml +resources/computation/normalize_access.ml +resources/computation/matmul_strict_annot.ml +resources/computation/make_strict_loop_contract.ml +resources/computation/ghost_clear.ml +record/set_explicit/record_set_explicit_doc.ml +record/set_explicit/record_set_explicit.ml +matrix/local_name_tile/matrix_local_name_tile_basic.ml +matrix/local_name_tile/matrix_local_name_tile.ml +matrix/elim_mops/matrix_elim_mops.ml +matrix/delete/matrix_delete.ml +loop/unroll_first_iterations/loop_unroll_first_iterations_doc.ml +loop/unroll_first_iterations/loop_unroll_first_iterations.ml +loop/unroll/loop_unroll_basic.ml +loop/split_range/loop_split_range_doc.ml +loop/split_range/loop_split_range.ml +loop/shift_range/loop_shift_range_basic.ml +loop/reorder_at/loop_reorder_at.ml +loop/rename_index/loop_rename_index.ml +loop/moveout/loop_moveout_alloc_basic.ml +loop/hoist/loop_hoist_basic.ml +loop/collapse/loop_collapse.ml +instr/gather/instr_gather.ml +function/elim_infix_ops/function_elim_infix_ops.ml +arith/simpl/arith_simpl_doc.ml +arith/simpl/arith_simpl.ml + +## failed +variable/unfold/variable_unfold_basic.ml +variable/unfold/variable_unfold.ml +variable/subst/variable_subst_doc.ml +variable/subst/variable_subst.ml +variable/reuse/variable_reuse_doc.ml +variable/reuse/variable_reuse.ml +variable/inline_and_rename/variable_inline_and_rename_doc.ml +variable/inline_and_rename/variable_inline_and_rename.ml +variable/inline/variable_inline_basic_doc.ml +variable/inline/variable_inline_basic.ml +variable/inline/variable_inline.ml +variable/elim_redundant/variable_elim_redundant_doc.ml +variable/elim_redundant/variable_elim_redundant.ml +variable/bind_syntactic/variable_bind_syntactic.ml +variable/bind_multi/variable_bind_multi.ml +sequence/intro/sequence_intro_basic.ml +sequence/elim/sequence_elim.ml +sequence/delete/sequence_delete.ml +resources/ghost_pure/ghost_pure_fission.ml +resources/ghost_pure/ghost_pure_copy_surrounding_inside.ml +resources/computation/loop_contracts.ml +reference/unfold/reference_unfold_doc.ml +reference/unfold/reference_unfold.ml +matrix/stack_copy/matrix_stack_copy.ml +loop/swap/loop_swap.ml +loop/shift_range/loop_shift_range_doc.ml +loop/shift_range/loop_shift_range.ml +loop/scale_range/loop_scale_range_doc.ml +loop/scale_range/loop_scale_range.ml +loop/reorder/loop_reorder_doc.ml +loop/reorder/loop_reorder.ml +loop/moveout/loop_moveout_basic.ml +loop/moveout/loop_moveout.ml +loop/fusion_targets/loop_fusion_targets_doc.ml +loop/fusion_targets/loop_fusion_targets.ml +loop/fusion/loop_fusion_doc.ml +loop/fusion/loop_fusion_basic_doc.ml +loop/fusion/loop_fusion_basic.ml +loop/fusion/loop_fusion.ml +loop/fission/loop_fission_doc.ml +loop/fission/loop_fission_basic_doc.ml +loop/fission/loop_fission_basic.ml +instr/moveout_of_fun/instr_moveout_of_fun_doc.ml +instr/moveout_of_fun/instr_moveout_of_fun.ml +instr/moveout/instr_moveout_doc.ml +instr/moveout/instr_moveout.ml +instr/move/instr_move_doc.ml +instr/move/instr_move_basic.ml +instr/move/instr_move.ml +function/uninline/function_uninline_basic.ml +function/inline_struct/function_inline_struct_doc.ml +function/inline_struct/function_inline_struct.ml +function/inline_simple/function_inline_simple_doc.ml +function/inline_simple/function_inline_simple.ml +function/inline_complex/function_inline_complex_doc.ml +function/inline_complex/function_inline_complex.ml +function/inline/function_inline.ml +function/delete/function_delete.ml +expr/replace_fun/expr_replace_fun.ml +accesses/shift/accesses_shift_doc.ml +accesses/shift/accesses_shift.ml +accesses/scale/accesses_scale_doc.ml +accesses/scale/accesses_scale.ml + # BROKEN TRANSFO TO FIX specialize/function_defs/specialize_function_defs_doc.ml specialize/function_defs/specialize_function_defs.ml diff --git a/tests/variable/local_name/variable_local_name.ml b/tests/variable/local_name/variable_local_name.ml index 0276c9a5d..1d4c6bd4b 100644 --- a/tests/variable/local_name/variable_local_name.ml +++ b/tests/variable/local_name/variable_local_name.ml @@ -1,30 +1,28 @@ -(* Deprecated *) open Optitrust open Prelude -(* let _ = Flags.check_validity := true *) +let _ = Flags.typechecking_mode := Flags.AnnotatedAndVerified let _ = Run.script_cpp (fun _ -> !! Variable.local_name ~var:"a" ~local_var:"x" [cFunBody "ok1"; cFor "i"]; !! Variable.local_name ~var:"a" ~local_var:"x" [cFunBody "ok2"; cLabel "l"]; -(* - !! Trace.failure_expected (fun _e -> true) (fun () -> - Variable.local_name ~var:"a" ~local_var:"x" [cFunBody "ko1"; cFor "i"]; - ); - !! Trace.failure_expected (fun _e -> true) (fun () -> + + (* !! Trace.resource_error_expected (fun () -> *) + !! Variable.local_name ~var:"a" ~local_var:"x" [cFunBody "ko1"; cFor "i"]; + (* ); *) + !! Trace.resource_error_expected (fun () -> Variable.local_name ~var:"b" ~local_var:"x" [cFunBody "ko1"; cFor "i"]; ); - !! Trace.failure_expected (fun _e -> true) (fun () -> + !! Trace.resource_error_expected (fun () -> Variable.local_name ~var:"a" ~local_var:"x" [cFunBody "ko2"; cLabel "l"] ); - !! Trace.failure_expected (fun _e -> true) (fun () -> + !! Trace.resource_error_expected (fun () -> Variable.local_name ~var:"b" ~local_var:"x" [cFunBody "ko2"; cLabel "l"] - ); *) + ); (* TODO: this triggers a renaming, should it throw an error instead? *) - (* Yanni : commenting this for the moment, since this works, but difficult to test. *) - (* !! Variable.local_name ~var:"a" ~local_var:"x" - [cFunBody "ko_scope"; cLabel "l"]; *) + !! Variable.local_name ~var:"a" ~local_var:"x" + [cFunBody "ko_scope"; cLabel "l"]; !! Variable.local_name ~var:"a" ~local_var:"x" [cFunBody "ok3"; tSpanSeq [cForBody "i"]]; diff --git a/tests/variable/local_name/variable_local_name_exp.cpp b/tests/variable/local_name/variable_local_name_exp.cpp index afb6f0723..ed30dff4c 100644 --- a/tests/variable/local_name/variable_local_name_exp.cpp +++ b/tests/variable/local_name/variable_local_name_exp.cpp @@ -20,7 +20,7 @@ void ok2() { __pure(); int a = 0; int x = a; -l : { x++; } +l: { x++; } a = x; int y = 0; } @@ -32,12 +32,14 @@ void ko1() { for (int j = 0; j < 10; j++) { __strict(); __smodifies("&a ~> Cell"); + int x = a; for (int i = 0; i < j; i++) { __strict(); - __smodifies("&a ~> Cell"); - a++; + __smodifies("&x ~> Cell"); + x++; b++; } + a = x; } int y = 0; } @@ -57,7 +59,9 @@ void ko_scope() { __pure(); int x = 0; int a = 0; -l: { a++; } + int x4 = a; +l: { x4++; } + a = x4; } void ok3() { diff --git a/tests/variable/unfold/variable_unfold_basic.ml b/tests/variable/unfold/variable_unfold_basic.ml index ad5290b8b..aaf6bfd90 100644 --- a/tests/variable/unfold/variable_unfold_basic.ml +++ b/tests/variable/unfold/variable_unfold_basic.ml @@ -1,3 +1,4 @@ +(* Deprecated *) open Optitrust open Target From 99cc7b3dceef8c48066b22d71aad1236c0ff57b8 Mon Sep 17 00:00:00 2001 From: Thomas Koehler Date: Fri, 24 Jul 2026 16:34:38 +0200 Subject: [PATCH 20/23] fix demo_show.ml --- lib/framework/show.ml | 5 ++++- lib/optilambda/optilambda_printer.ml | 25 +++++++++++++++++-------- lib/transfo/loop_basic.ml | 3 +-- tests/ast/demo_show.cpp | 2 +- tests/ast/demo_show.ml | 1 + tests/ast/demo_show_exp.cpp | 21 ++++++++++----------- 6 files changed, 34 insertions(+), 23 deletions(-) diff --git a/lib/framework/show.ml b/lib/framework/show.ml index 633e529ff..194e2848a 100644 --- a/lib/framework/show.ml +++ b/lib/framework/show.ml @@ -91,7 +91,10 @@ let trm ?(style = optilambda ()) ?(msg : string = "") (t : trm) : unit = let st = match style.print with | Lang_OptiLambda optilambda_style -> - Optitrust_optilambda.Optilambda.trm_to_string ~style:optilambda_style t + if Trm.trm_is_mainfile t + (* FIXME: optilambda printer should probably know this through term annots ? *) + then Optitrust_optilambda.Optilambda.program_to_string ~style:optilambda_style ~header:(Trace.get_context ()).header t + else Optitrust_optilambda.Optilambda.trm_to_string ~style:optilambda_style t | Lang_AST ast_style -> let t = prepare_encoded_term t in Ast_to_text.ast_to_string ~style:ast_style t diff --git a/lib/optilambda/optilambda_printer.ml b/lib/optilambda/optilambda_printer.ml index 813f051c4..636eba1e4 100644 --- a/lib/optilambda/optilambda_printer.ml +++ b/lib/optilambda/optilambda_printer.ml @@ -917,6 +917,8 @@ and let_to_doc (style : Optilambda_style.style) ((v, ty) : typed_var) (body : tr and app_to_doc (style : Optilambda_style.style) ~(result_typ : typ) (f : trm) (args : trm list) (ghost_args : resource_item list) (ghost_bind : (var option * var) list) : document = match (f.desc, args) with + | Trm_var ignore_var, [arg] when var_eq ignore_var var_ignore -> + trm_to_doc_at style 0 arg | Trm_var group_var, [ { desc = Trm_apps ({ desc = Trm_var range_var; _ }, [ start; stop; step ], [], []); _ }; { desc = Trm_fun ([ (index, _) ], _, body, _); _ } ] when style.representation = Surface && group_var.name = "Group" && group_var.namespaces = [] && range_var.name = "range" @@ -980,8 +982,13 @@ and app_to_doc (style : Optilambda_style.style) ~(result_typ : typ) (f : trm) (a | Trm_prim (_, Prim_unop Unop_get), [ arg ] when is_explicit_internal style -> name_with_optional_type_arg style "get" result_typ ^^ parens_doc (trm_to_doc_at style 0 arg) | Trm_prim (_, Prim_unop Unop_get), [ arg ] -> trm_to_doc_at style 8 arg - | Trm_prim (_, Prim_unop Unop_address), [ arg ] -> string "&" ^^ trm_to_doc_at style 8 arg - | Trm_prim (_, Prim_unop Unop_minus), [ arg ] -> string "-" ^^ trm_to_doc_at style 8 arg + | Trm_prim (_, Prim_unop Unop_address), [ arg ] when is_surface style -> string "&" ^^ trm_to_doc_at style 8 arg + | Trm_prim (_, Prim_unop Unop_minus), [ arg ] when is_surface style -> string "-" ^^ trm_to_doc_at style 8 arg + | Trm_prim (_, Prim_unop Unop_plus), [ arg ] when is_surface style -> string "+" ^^ trm_to_doc_at style 8 arg + | Trm_prim (_, Prim_unop Unop_pre_incr), [ arg ] when is_surface style -> twice plus ^^ trm_to_doc_at style 8 arg + | Trm_prim (_, Prim_unop Unop_post_incr), [ arg ] when is_surface style -> trm_to_doc_at style 8 arg ^^ twice plus + | Trm_prim (_, Prim_unop Unop_pre_decr), [ arg ] when is_surface style -> twice minus ^^ trm_to_doc_at style 8 arg + | Trm_prim (_, Prim_unop Unop_post_decr), [ arg ] when is_surface style -> trm_to_doc_at style 8 arg ^^ twice minus | Trm_prim (_, Prim_unop Unop_neg), [ arg ] -> string "not" ^^ blank 1 ^^ trm_to_doc_at style 8 arg | Trm_prim (_, Prim_unop (Unop_cast cast_ty)), [ arg ] -> string "cast" ^^ angles_doc (typ_to_doc style cast_ty) ^^ parens_doc (trm_to_doc_at style 0 arg) @@ -1062,6 +1069,7 @@ and instrs_to_block_items (style : Optilambda_style.style) (instrs : trm list) : match instrs with | [] -> List.rev acc | [ { desc = Trm_abort (Ret (Some ret)); _ } ] -> List.rev (FinalExpr (trm_to_doc_at style 0 ret) :: acc) + | instr :: rest when trm_is_include instr -> aux acc rest | instr :: rest -> let is_fun = is_function_definition instr in let acc = if is_fun && acc <> [] then Blank :: acc else acc in @@ -1167,7 +1175,9 @@ and trm_to_doc_at (style : Optilambda_style.style) (ctx_prec : int) (t : trm) : | Trm_lit lit -> lit_to_doc style lit | Trm_prim (ty, prim) -> prim_to_doc style ty prim | Trm_let (typed_var, body) -> let_to_doc style typed_var body - | Trm_let_mult bindings -> block_doc (List.map (fun (typed_var, body) -> let_to_doc style typed_var body) bindings) + | Trm_let_mult bindings -> + (* NOTE: should this case exist ? *) + semi_sep (List.map (fun (typed_var, body) -> let_to_doc style typed_var body) bindings) | Trm_predecl typed_var -> string "let" ^^ blank 1 ^^ typed_var_to_doc style typed_var | Trm_fun (args, ret_ty, body, spec) -> fun_def_to_doc style None args ret_ty spec body | Trm_typedef _ -> typedef_to_doc style t @@ -1227,12 +1237,11 @@ and trm_to_doc (style : Optilambda_style.style) (t : trm) : document = trm_to_do output describes the source program without expanding every included declaration. *) let program_to_doc (style : Optilambda_style.style) ~(header : string) (t : trm) : document = let include_docs = header_to_docs header in - let program = - match t.desc with + let program = match t.desc with | Trm_seq (instrs, result) -> - let main_file = main_source_file t in - trm_to_doc style { t with desc = Trm_seq (Mlist.filter (fun instr -> not (is_from_included_file main_file instr)) instrs, result) } - | _ -> trm_to_doc style t + let main_file = main_source_file t in + separate (semi ^^ twice hardline) (List.map (trm_to_doc style) (List.filter (fun instr -> not (is_from_included_file main_file instr)) (Mlist.to_list instrs))) + | _ -> failwith "expected root sequence on main file" in match include_docs with | [] -> program diff --git a/lib/transfo/loop_basic.ml b/lib/transfo/loop_basic.ml index 4c0b0a81b..ef343e526 100644 --- a/lib/transfo/loop_basic.ml +++ b/lib/transfo/loop_basic.ml @@ -428,8 +428,7 @@ let%transfo fission_basic ?(mark_loops : mark = no_mark) ?(mark_between_loops : (* DEBUG: let debug_p = Path.parent p_loop in Show.res ~msg:"res1" ~ast:(get_trm_at_exn (target_of_path debug_p)) ); *) - if !Flags.check_validity || !Flags.use_resources_with_models - then Resources.ensure_computed (); + if Flags.annotated_and_verified () then Resources.ensure_computed (); apply_at_path (fission_on mark_loops mark_between_loops split_i) p_loop; ) tg ); diff --git a/tests/ast/demo_show.cpp b/tests/ast/demo_show.cpp index eb52c7547..dd855f247 100644 --- a/tests/ast/demo_show.cpp +++ b/tests/ast/demo_show.cpp @@ -6,7 +6,7 @@ int main() { x--; for (int i = 0; i < 3; i++) { __strict(); - __smodifies("x ~> Cell"); + __smodifies("&x ~> Cell"); x++; } } diff --git a/tests/ast/demo_show.ml b/tests/ast/demo_show.ml index 236e95aa8..40340d040 100644 --- a/tests/ast/demo_show.ml +++ b/tests/ast/demo_show.ml @@ -5,6 +5,7 @@ let has_reference (t : trm) : bool = Trm.trm_get_cstyles t = [Reference] let _ = Run.script_cpp ~capture_show_in_batch:true (fun () -> + !! Resources.ensure_computed (); !! Show.At.trm ~msg:"AST" []; (*!! Show.At.trm ~msg:"for trm" [cFor "i"]; --> need decoding of nonroot*) (* TODO: ensure a deterministic printing of identifiers diff --git a/tests/ast/demo_show_exp.cpp b/tests/ast/demo_show_exp.cpp index f5e834346..61a5e689d 100644 --- a/tests/ast/demo_show_exp.cpp +++ b/tests/ast/demo_show_exp.cpp @@ -6,25 +6,24 @@ int main() { x--; for (int i = 0; i < 3; i++) { __strict(); - __smodifies("x ~> Cell"); + __smodifies("&x ~> Cell"); /*@mymark2, mymark1*/ x /*mymark2, mymark1@*/++; } } /* CAPTURED STDOUT: -AST: +AST: include "../../include/optitrust.h"; - - - int main () { - int a, b; - int x = 3; +fun main(): int { + letmut a; + letmut b; + letmut x = 3; x--; - for (int i = 0; i < 3; i++) { - __strict(); - __smodifies("x ~> Cell"); + for i in 0..3 { + strict; + spreserves x ~> CellOf(Any); x++; - } + }; } for-trm-internal-desc: Trm_for (seq, i, From 2c8f41dac649f00c30962b41b570513041704f30 Mon Sep 17 00:00:00 2001 From: Thomas Koehler Date: Mon, 27 Jul 2026 18:02:38 +0200 Subject: [PATCH 21/23] go through case studies after merge, looks like reduce got broken --- case_studies/dot_product/dot.ml | 2 +- case_studies/gpu/histogram/hist.ml | 2 +- case_studies/gpu/matmul/matmul.ml | 4 +- case_studies/gpu/matmul/matmul_exp.cu | 65 ++- case_studies/gpu/reduction/reduce.ml | 4 +- case_studies/matmul/matmul_models_exp.cpp | 485 ++++++++++++++++++ .../opencv/box_filter_rowsum_models.ml | 4 +- lib/framework/c/ast_to_c.ml | 8 +- lib/framework/prelude.ml | 2 +- lib/framework/runtime/trace.ml | 11 +- lib/transfo/accesses_basic.ml | 3 +- lib/transfo/arith.ml | 6 +- lib/transfo/cleanup.ml | 1 + lib/transfo/instr.ml | 6 +- lib/transfo/loop.ml | 2 + lib/transfo/loop_basic.ml | 2 +- lib/transfo/loop_core.ml | 5 +- lib/transfo/variable_core.ml | 2 +- 18 files changed, 564 insertions(+), 50 deletions(-) create mode 100644 case_studies/matmul/matmul_models_exp.cpp diff --git a/case_studies/dot_product/dot.ml b/case_studies/dot_product/dot.ml index bbb297402..8e61a1b0b 100644 --- a/case_studies/dot_product/dot.ml +++ b/case_studies/dot_product/dot.ml @@ -3,7 +3,7 @@ open Prelude let _ = Flags.typechecking_mode := Flags.AnnotatedAndVerified let _ = Flags.pretty_matrix_notation := false -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.recompute_resources_between_steps := true *) let _ = Flags.disable_stringreprs := true let _ = Flags.save_ast_for_steps := Some Flags.Steps_all (*Steps_important*) diff --git a/case_studies/gpu/histogram/hist.ml b/case_studies/gpu/histogram/hist.ml index f7d273f1c..da6981aad 100644 --- a/case_studies/gpu/histogram/hist.ml +++ b/case_studies/gpu/histogram/hist.ml @@ -4,7 +4,7 @@ open Prelude (* let _ = Flags.check_validity := true *) let _ = Flags.typechecking_mode := Flags.AnnotatedAndVerified let _ = Flags.pretty_matrix_notation := true -let _ = Flags.recompute_resources_between_steps := true +(* let _ = Flags.recompute_resources_between_steps := true *) let _ = Flags.disable_stringreprs := true let _ = Flags.save_ast_for_steps := Some Flags.Steps_important diff --git a/case_studies/gpu/matmul/matmul.ml b/case_studies/gpu/matmul/matmul.ml index 984ec1f16..c2bfbcf41 100644 --- a/case_studies/gpu/matmul/matmul.ml +++ b/case_studies/gpu/matmul/matmul.ml @@ -3,7 +3,7 @@ open Prelude let _ = Flags.typechecking_mode := Flags.AnnotatedAndVerified let _ = Flags.pretty_matrix_notation := false -let _ = Flags.recompute_resources_between_steps := false +(* let _ = Flags.recompute_resources_between_steps := false *) let _ = Flags.disable_stringreprs := true let _ = Flags.save_ast_for_steps := Some Steps_effectful (* Flags.Steps_script *) @@ -97,8 +97,6 @@ let _ = Run.script_cpp_stage stage_ok (fun () -> !! Loop.hoist_instr ~down:true ~dest:[tAfter; cFor ~body:[cWrite ~lhs:[cVar "c_gmem"] ()] "bi"] [cMark "s4"]; ) -let _ = Flags.check_validity := false - let _ = Run.script_cpp_stage stage_ok (fun () -> (* Construct terms to pass to kernel_launch *) (* LATER: cleaner frontend for building terms *) diff --git a/case_studies/gpu/matmul/matmul_exp.cu b/case_studies/gpu/matmul/matmul_exp.cu index c00216f9b..1a2160bf2 100644 --- a/case_studies/gpu/matmul/matmul_exp.cu +++ b/case_studies/gpu/matmul/matmul_exp.cu @@ -1,11 +1,6 @@ #include - - - - - const int bm = 32; const int bn = 32; @@ -16,13 +11,15 @@ const int tn = 4; const int tm = 8; - __global__ void __kernel0 (float* b_gmem, float* a_gmem, float* c_gmem, int p, int n, int m -) { - const int __ctx_sz = MSIZE2(exact_div(m, 32), exact_div(n, 32)) * MSIZE2(exact_div(32, 8), exact_div(32, 4)); - const int __tid = blockIdx.x * MSIZE2(exact_div(32, 8), exact_div(32, 4)) + threadIdx.x; +__global__ void __kernel0(float* b_gmem, float* a_gmem, float* c_gmem, int p, + int n, int m) { + const int __ctx_sz = MSIZE2(exact_div(m, 32), exact_div(n, 32)) * + MSIZE2(exact_div(32, 8), exact_div(32, 4)); + const int __tid = + blockIdx.x * MSIZE2(exact_div(32, 8), exact_div(32, 4)) + threadIdx.x; SharedMemory smem; - float* const b_smem = (float*) smem.ptr(MSIZE3(8, 4, 4)); - float* const a_smem = (float*) smem.ptr(MSIZE3(4, 4, 8)); + float* const b_smem = (float*)smem.ptr(MSIZE3(8, 4, 4)); + float* const a_smem = (float*)smem.ptr(MSIZE3(4, 4, 8)); const int __ctx_sz_0 = __ctx_sz / (exact_div(m, 32)); const int __bi0 = __tid % __ctx_sz / __ctx_sz_0; const int __ctx_sz_1 = __ctx_sz_0 / (exact_div(n, 32)); @@ -55,50 +52,64 @@ const int tm = 8; } for (int bkIdx = 0; bkIdx < exact_div(p, 4); bkIdx++) { for (int k = 0; k < 4; k++) { - a_smem[MINDEX4(exact_div(m, 32) * (exact_div(n, 32)), 4, 4, 8, 0, __ti4, k, __i5)] = a_gmem[MINDEX2(m, p, __bi0 * 32 + ( - __ti4 * 8 + __i5), bkIdx * 4 + k)]; + a_smem[MINDEX4(exact_div(m, 32) * (exact_div(n, 32)), 4, 4, 8, 0, __ti4, + k, __i5)] = + a_gmem[MINDEX2(m, p, __bi0 * 32 + (__ti4 * 8 + __i5), bkIdx * 4 + k)]; } for (int j = 0; j < 4; j++) { - b_smem[MINDEX4(exact_div(m, 32) * (exact_div(n, 32)), 8, 4, 4, 0, __tj6, __k7, j)] = b_gmem[MINDEX2(p, n, bkIdx * 4 + __k7, __bj1 * 32 + ( - __tj6 * 4 + j))]; + b_smem[MINDEX4(exact_div(m, 32) * (exact_div(n, 32)), 8, 4, 4, 0, __tj6, + __k7, j)] = + b_gmem[MINDEX2(p, n, bkIdx * 4 + __k7, __bj1 * 32 + (__tj6 * 4 + j))]; } __syncthreads(); - for (int i = 0; i < 8; i++) { for (int j = 0; j < 4; j++) { } } + for (int i = 0; i < 8; i++) { + for (int j = 0; j < 4; j++) { + } + } for (int k = 0; k < 4; k++) { float* const a_regs = __treg_ref_uninit1_s(8); for (int i = 0; i < 8; i++) { - a_regs[MINDEX1(8, i)] = a_smem[MINDEX4(exact_div(m, 32) * (exact_div(n, 32) - ), 4, 4, 8, 0, __ti8, k, i)]; + a_regs[MINDEX1(8, i)] = a_smem[MINDEX4( + exact_div(m, 32) * (exact_div(n, 32)), 4, 4, 8, 0, __ti8, k, i)]; } float* const b_regs = __treg_ref_uninit1_s(4); for (int j = 0; j < 4; j++) { - b_regs[MINDEX1(4, j)] = b_smem[MINDEX4(exact_div(m, 32) * (exact_div(n, 32) - ), 8, 4, 4, 0, __tj9, k, j)]; + b_regs[MINDEX1(4, j)] = b_smem[MINDEX4( + exact_div(m, 32) * (exact_div(n, 32)), 8, 4, 4, 0, __tj9, k, j)]; } for (int i = 0; i < 8; i++) { for (int j = 0; j < 4; j++) { - sum[MINDEX3(4 * 8, 8, 4, 0, i, j)] = sum[MINDEX3(4 * 8, 8, 4, 0, i, j)] + a_regs[MINDEX1(8, i)] * b_regs[MINDEX1(4, j)]; + sum[MINDEX3(4 * 8, 8, 4, 0, i, j)] = + sum[MINDEX3(4 * 8, 8, 4, 0, i, j)] + + a_regs[MINDEX1(8, i)] * b_regs[MINDEX1(4, j)]; } } } - for (int i = 0; i < 8; i++) { for (int j = 0; j < 4; j++) { } } + for (int i = 0; i < 8; i++) { + for (int j = 0; j < 4; j++) { + } + } } for (int i = 0; i < 8; i++) { for (int j = 0; j < 4; j++) { - c_gmem[MINDEX2(m, n, __bi0 * 32 + (__ti10 * 8 + i), __bj1 * 32 + (__tj11 * 4 + j - ))] = sum[MINDEX3(4 * 8, 8, 4, 0, i, j)]; + c_gmem[MINDEX2(m, n, __bi0 * 32 + (__ti10 * 8 + i), + __bj1 * 32 + (__tj11 * 4 + j))] = + sum[MINDEX3(4 * 8, 8, 4, 0, i, j)]; } } } - void mm (float* c, float* a, float* b, int m, int n, int p) { +void mm(float* c, float* a, float* b, int m, int n, int p) { float* const c_gmem = __gmem_malloc2(m, n); float* const a_gmem = __gmem_malloc2(m, p); memcpy_host_to_device2(a_gmem, a, m, p); float* const b_gmem = __gmem_malloc2(p, n); memcpy_host_to_device2(b_gmem, b, p, n); - __kernel0<<>>(b_gmem, a_gmem, c_gmem, p, n, m); + __kernel0<<>>(b_gmem, a_gmem, c_gmem, + p, n, m); gmem_free(b_gmem); gmem_free(a_gmem); memcpy_device_to_host2(c, c_gmem, m, n); diff --git a/case_studies/gpu/reduction/reduce.ml b/case_studies/gpu/reduction/reduce.ml index c68ca8172..6349f7602 100644 --- a/case_studies/gpu/reduction/reduce.ml +++ b/case_studies/gpu/reduction/reduce.ml @@ -4,7 +4,7 @@ open Prelude (* let _ = Flags.check_validity := true *) let _ = Flags.use_resources_with_models := true (* let _ = Flags.preserve_specs_only := true *) -let _ = Flags.typechecking_mode := Flags.Annotated +let _ = Flags.typechecking_mode := Flags.AnnotatedAndVerified let _ = Flags.pretty_matrix_notation := false let _ = Flags.recompute_resources_between_steps := true (* FIXME: should be false *) let _ = Flags.disable_stringreprs := true @@ -184,6 +184,8 @@ let _ = Run.script_cpp_stage stage_ok (fun () -> But it's also not declared on the host level. Normally, having a variable as thread for loop bounds is illegal, but this is just a pure constant, so it can be inlined as a quick fix to the problem. *) !! Variable.inline [cVarDef ~regexp:true "N.+"]; + + !! Resources.ensure_computed (); !! Flags.recompute_resources_between_steps := false; !! Trace.without_substep_validity_checks (fun () -> Instr.move ~dest:[tFirst; cMark "kernel_sequence"] [cCall "kernel_launch"]; diff --git a/case_studies/matmul/matmul_models_exp.cpp b/case_studies/matmul/matmul_models_exp.cpp new file mode 100644 index 000000000..d46f9baee --- /dev/null +++ b/case_studies/matmul/matmul_models_exp.cpp @@ -0,0 +1,485 @@ +#include + +#include "omp.h" + +__ghost(assert_inhabited, "x := arbitrary(int * (int -> float) -> float)", + "reduce_sum <- x"); + +__ghost(assert_prop, + "proof := admit(forall (f: int -> float) -> (0.f =. reduce_sum(0, f)))", + "reduce_sum_empty <- proof"); + +__ghost(assert_prop, + "proof := admit(forall (n: int) (f: int -> float) (_: (n >= 0)) -> " + "(reduce_sum(n, f) +. f(n) =. reduce_sum(n + 1, f)))", + "reduce_sum_add_right <- proof"); + +__ghost(define, + "x := fun (A: int * int -> float) (B: int * int -> float) (p: int) -> " + "fun (i: int) (j: int) -> reduce_sum(p, fun k -> A(i, k) *. B(k, j))", + "matmul <- x"); + +void mm1024(float* c, float* a, float* b) { + __requires("A: int * int -> float"); + __requires("B: int * int -> float"); + __writes("c ~> Matrix2(1024, 1024, matmul(A, B, 1024))"); + __reads("a ~> Matrix2(1024, 1024, A)"); + __reads("b ~> Matrix2(1024, 1024, B)"); + __ghost(assert_prop, "P := (1024 = 32 * 32)", "tile_div_check_i <- proof"); + __ghost(tile_divides, + "div_check := tile_div_check_i, items := fun (i: int) -> for j in " + "0..1024 -> &c[MINDEX2(1024, 1024, i, j)] ~> UninitCell"); + float* const bT = (float*)malloc(MSIZE4(32, 256, 4, 32) * sizeof(float)); +#pragma omp parallel for + for (int bj = 0; bj < 32; bj++) { + __strict(); + __sreads("b ~> Matrix2(1024, 1024, B)"); + __xwrites( + "for bk in 0..256 -> for k in 0..4 -> for j in 0..32 -> " + "&bT[MINDEX4(32, 256, 4, 32, bj, bk, k, j)] ~~> B(bk * 4 + k, bj * 32 " + "+ j)"); + for (int bk = 0; bk < 256; bk++) { + __strict(); + __sreads("b ~> Matrix2(1024, 1024, B)"); + __xwrites( + "for k in 0..4 -> for j in 0..32 -> &bT[MINDEX4(32, 256, 4, 32, bj, " + "bk, k, j)] ~~> B(bk * 4 + k, bj * 32 + j)"); + __ghost(assert_prop, "P := (1024 = 32 * 32)", + "tile_div_check_j512 <- proof"); + for (int k = 0; k < 4; k++) { + __strict(); + __sreads("b ~> Matrix2(1024, 1024, B)"); + __xwrites( + "for j in 0..32 -> &bT[MINDEX4(32, 256, 4, 32, bj, bk, k, j)] ~~> " + "B(bk * 4 + k, bj * 32 + j)"); + for (int j = 0; j < 32; j++) { + __strict(); + __sreads("b ~> Matrix2(1024, 1024, B)"); + __xwrites( + "&bT[MINDEX4(32, 256, 4, 32, bj, bk, k, j)] ~~> B(bk * 4 + k, bj " + "* 32 + j)"); + __ghost(assert_prop, "P := (1024 = 256 * 4)", + "tile_div_check_k13 <- proof"); + __ghost( + tiled_index_in_range, + "tile_index := bk, index := k, div_check := tile_div_check_k13", + ""); + __ghost( + tiled_index_in_range, + "tile_index := bj, index := j, div_check := tile_div_check_j512", + ""); + const __ghost_fn __ghost_pair_3 = + __ghost_begin(ro_matrix2_focus, + "matrix := b, i := bk * 4 + k, j := bj * 32 + j"); + bT[MINDEX4(32, 256, 4, 32, bj, bk, k, j)] = + b[MINDEX2(1024, 1024, bk * 4 + k, bj * 32 + j)]; + __ghost_end(__ghost_pair_3); + } + } + } + } +#pragma omp parallel for + for (int bi = 0; bi < 32; bi++) { + __strict(); + __sreads( + "for bj in 0..32 -> for bk in 0..256 -> for k in 0..4 -> for j in " + "0..32 -> &bT[MINDEX4(32, 256, 4, 32, bj, bk, k, j)] ~~> B(bk * 4 + k, " + "bj * 32 + j)"); + __sreads("a ~> Matrix2(1024, 1024, A)"); + __xwrites( + "for i in 0..32 -> for j in 0..1024 -> &c[MINDEX2(1024, 1024, bi * 32 " + "+ i, j)] ~~> matmul(A, B, 1024)(bi * 32 + i, j)"); + for (int i = 0; i < 32; i++) { + __strict(); + __xconsumes( + "for j in 0..1024 -> &c[MINDEX2(1024, 1024, bi * 32 + i, j)] ~> " + "UninitCell"); + __xproduces( + "for bi6 in 0..32 -> for i7 in 0..32 -> &c[MINDEX2(1024, 1024, bi * " + "32 + i, bi6 * 32 + i7)] ~> UninitCell"); + __ghost(assert_prop, "P := (1024 = 32 * 32)", + "tile_div_check_j <- proof"); + __ghost(tile_divides, + "div_check := tile_div_check_j, items := fun (j: int) -> " + "&c[MINDEX2(1024, 1024, bi * 32 + i, j)] ~> UninitCell"); + } + __ghost(swap_groups, + "outer_range := 0..32, inner_range := 0..32, items := fun (i: int) " + "(bj: int) -> for j in 0..32 -> &c[MINDEX2(1024, 1024, bi * 32 + " + "i, bj * 32 + j)] ~> UninitCell"); + for (int bj = 0; bj < 32; bj++) { + __strict(); + __sreads("a ~> Matrix2(1024, 1024, A)"); + __xwrites( + "for i in 0..32 -> for j in 0..32 -> &c[MINDEX2(1024, 1024, bi * 32 " + "+ i, bj * 32 + j)] ~~> matmul(A, B, 1024)(bi * 32 + i, bj * 32 + " + "j)"); + __xreads( + "for bk in 0..256 -> for k in 0..4 -> for j in 0..32 -> " + "&bT[MINDEX4(32, 256, 4, 32, bj, bk, k, j)] ~~> B(bk * 4 + k, bj * " + "32 + j)"); + float* const sum = (float*)malloc(MSIZE2(32, 32) * sizeof(float)); + for (int i = 0; i < 32; i++) { + __strict(); + __xwrites( + "for j in 0..32 -> &sum[MINDEX2(32, 32, i, j)] ~~> reduce_sum(0 * " + "4, fun k0 -> A(bi * 32 + i, k0) *. B(k0, bj * 32 + j))"); + for (int j = 0; j < 32; j++) { + __strict(); + __xwrites( + "&sum[MINDEX2(32, 32, i, j)] ~~> reduce_sum(0 * 4, fun k0 -> " + "A(bi * 32 + i, k0) *. B(k0, bj * 32 + j))"); + sum[MINDEX2(32, 32, i, j)] = 0.f; + __ghost(rewrite_float_linear, + "inside := fun v -> &sum[MINDEX2(32, 32, i, j)] ~~> v, by := " + "reduce_sum_empty(fun k -> A(bi * 32 + i, k) *. B(k, bj * 32 " + "+ j))"); + __ghost(rewrite_linear, + "inside := fun (k: int) -> &sum[MINDEX2(32, 32, i, j)] ~~> " + "reduce_sum(k, fun k0 -> A(bi * 32 + i, k0) *. B(k0, bj * 32 " + "+ j)), by := zero_mul_intro(4)"); + } + } + for (int bk = 0; bk < 256; bk++) { + __strict(); + __spreserves( + "for i in 0..32 -> for j in 0..32 -> &sum[MINDEX2(32, 32, i, j)] " + "~~> reduce_sum(bk * 4, fun k0 -> A(bi * 32 + i, k0) *. B(k0, bj * " + "32 + j))"); + __sreads("a ~> Matrix2(1024, 1024, A)"); + __xreads( + "for k in 0..4 -> for j in 0..32 -> &bT[MINDEX4(32, 256, 4, 32, " + "bj, bk, k, j)] ~~> B(bk * 4 + k, bj * 32 + j)"); + __ghost(assert_prop, "P := (1024 = 32 * 32)", + "tile_div_check_j51222 <- proof"); + for (int i = 0; i < 32; i++) { + __strict(); + __sreads( + "for k in 0..4 -> for j in 0..32 -> &bT[MINDEX4(32, 256, 4, 32, " + "bj, bk, k, j)] ~~> B(bk * 4 + k, bj * 32 + j)"); + __sreads("a ~> Matrix2(1024, 1024, A)"); + __xconsumes( + "for j in 0..32 -> &sum[MINDEX2(32, 32, i, j)] ~~> reduce_sum(bk " + "* 4, fun k0 -> A(bi * 32 + i, k0) *. B(k0, bj * 32 + j))"); + __xproduces( + "for j in 0..32 -> &sum[MINDEX2(32, 32, i, j)] ~~> " + "reduce_sum((bk + 1) * 4, fun k0 -> A(bi * 32 + i, k0) *. B(k0, " + "bj * 32 + j))"); + for (int j = 0; j < 32; j++) { + __strict(); + __xconsumes( + "&sum[MINDEX2(32, 32, i, j)] ~~> reduce_sum(bk * 4, fun k0 -> " + "A(bi * 32 + i, k0) *. B(k0, bj * 32 + j))"); + __xproduces( + "&sum[MINDEX2(32, 32, i, j)] ~~> reduce_sum(bk * 4 + 0, fun k0 " + "-> A(bi * 32 + i, k0) *. B(k0, bj * 32 + j))"); + __ghost(rewrite_linear, + "inside := fun (k: int) -> &sum[MINDEX2(32, 32, i, j)] ~~> " + "reduce_sum(k, fun k0 -> A(bi * 32 + i, k0) *. B(k0, bj * " + "32 + j)), by := plus_zero_intro(bk * 4)"); + } + __ghost(tiled_index_in_range, + "tile_index := bi, index := i, div_check := tile_div_check_i", + ""); + float s[MSIZE1(32)]; + const __ghost_fn __ghost_pair_6 = + __ghost_begin(ro_mindex2_unfold, + "H := fun (access: int * int -> float*) -> for j " + "in 0..32 -> access(i, j) ~~> reduce_sum(bk * 4 + " + "0, fun k0 -> A(bi * 32 + i, k0) *. B(k0, bj * 32 " + "+ j)), matrix := sum, n1 := 32, n2 := 32"); + MATRIX1_COPY_float(s, &sum[i * 32], 32); + __ghost_end(__ghost_pair_6); + __ghost(assume, "P := in_range(0, 0..4)"); + __ghost(assume, "P := in_range(1, 0..4)"); + __ghost(assume, "P := in_range(2, 0..4)"); + __ghost(assume, "P := in_range(3, 0..4)"); + const __ghost_fn __ghost_pair_7 = + __ghost_begin(ro_group_focus, + "i := 0, items := fun (k: int) -> for j in 0..32 " + "-> &bT[MINDEX4(32, 256, 4, 32, bj, bk, k, j)] ~~> " + "B(bk * 4 + k, bj * 32 + j)"); +#pragma omp simd + for (int j = 0; j < 32; j++) { + __strict(); + __sreads("a ~> Matrix2(1024, 1024, A)"); + __xconsumes( + "&s[MINDEX1(32, j)] ~~> reduce_sum(bk * 4 + 0, fun k0 -> A(bi " + "* 32 + i, k0) *. B(k0, bj * 32 + j))"); + __xproduces( + "&s[MINDEX1(32, j)] ~~> reduce_sum(bk * 4 + (0 + 1), fun k0 -> " + "A(bi * 32 + i, k0) *. B(k0, bj * 32 + j))"); + __xreads( + "&bT[MINDEX4(32, 256, 4, 32, bj, bk, 0, j)] ~~> B(bk * 4 + 0, " + "bj * 32 + j)"); + __ghost(tiled_index_in_range, + "tile_index := bj, index := j, div_check := " + "tile_div_check_j51222", + ""); + __ghost(assert_prop, "P := (1024 = 256 * 4)", + "tile_div_check_k1320 <- proof"); + __ghost(tiled_index_in_range, + "tile_index := bk, index := 0, div_check := " + "tile_div_check_k1320", + ""); + const __ghost_fn __ghost_pair_2 = + __ghost_begin(ro_matrix2_focus, + "matrix := a, i := bi * 32 + i, j := bk * 4 + 0"); + s[MINDEX1(32, j)] += + a[MINDEX2(1024, 1024, bi * 32 + i, bk * 4 + 0)] * + bT[MINDEX4(32, 256, 4, 32, bj, bk, 0, j)]; + __ghost_end(__ghost_pair_2); + __ghost(in_range_bounds, "x := bk * 4 + 0", + "k_ge_021 <- lower_bound, #_23 <- upper_bound"); + __ghost(rewrite_float_linear, + "inside := fun v -> &s[MINDEX1(32, j)] ~~> v, by := " + "reduce_sum_add_right(bk * 4 + 0, fun k -> A(bi * 32 + i, " + "k) *. B(k, bj * 32 + j), k_ge_021)"); + __ghost(rewrite_linear, + "inside := fun (k: int) -> &s[MINDEX1(32, j)] ~~> " + "reduce_sum(k, fun k0 -> A(bi * 32 + i, k0) *. B(k0, bj * " + "32 + j)), by := add_assoc_right(bk * 4, 0, 1)"); + } + __ghost_end(__ghost_pair_7); + __ghost(rewrite_linear, + "from := 0 + 1, to := 1, inside := fun (k: int) -> for j in " + "0..32 -> &s[MINDEX1(32, j)] ~~> reduce_sum(bk * 4 + k, fun " + "k0 -> A(bi * 32 + i, k0) *. B(k0, bj * 32 + j))"); + const __ghost_fn __ghost_pair_723 = + __ghost_begin(ro_group_focus, + "i := 1, items := fun (k: int) -> for j in 0..32 " + "-> &bT[MINDEX4(32, 256, 4, 32, bj, bk, k, j)] ~~> " + "B(bk * 4 + k, bj * 32 + j)"); +#pragma omp simd + for (int j = 0; j < 32; j++) { + __strict(); + __sreads("a ~> Matrix2(1024, 1024, A)"); + __xconsumes( + "&s[MINDEX1(32, j)] ~~> reduce_sum(bk * 4 + 1, fun k0 -> A(bi " + "* 32 + i, k0) *. B(k0, bj * 32 + j))"); + __xproduces( + "&s[MINDEX1(32, j)] ~~> reduce_sum(bk * 4 + (1 + 1), fun k0 -> " + "A(bi * 32 + i, k0) *. B(k0, bj * 32 + j))"); + __xreads( + "&bT[MINDEX4(32, 256, 4, 32, bj, bk, 1, j)] ~~> B(bk * 4 + 1, " + "bj * 32 + j)"); + __ghost(tiled_index_in_range, + "tile_index := bj, index := j, div_check := " + "tile_div_check_j51222", + ""); + __ghost(assert_prop, "P := (1024 = 256 * 4)", + "tile_div_check_k1320 <- proof"); + __ghost(tiled_index_in_range, + "tile_index := bk, index := 1, div_check := " + "tile_div_check_k1320", + ""); + const __ghost_fn __ghost_pair_2 = + __ghost_begin(ro_matrix2_focus, + "matrix := a, i := bi * 32 + i, j := bk * 4 + 1"); + s[MINDEX1(32, j)] += + a[MINDEX2(1024, 1024, bi * 32 + i, bk * 4 + 1)] * + bT[MINDEX4(32, 256, 4, 32, bj, bk, 1, j)]; + __ghost_end(__ghost_pair_2); + __ghost(in_range_bounds, "x := bk * 4 + 1", + "k_ge_021 <- lower_bound, #_23 <- upper_bound"); + __ghost(rewrite_float_linear, + "inside := fun v -> &s[MINDEX1(32, j)] ~~> v, by := " + "reduce_sum_add_right(bk * 4 + 1, fun k -> A(bi * 32 + i, " + "k) *. B(k, bj * 32 + j), k_ge_021)"); + __ghost(rewrite_linear, + "inside := fun (k: int) -> &s[MINDEX1(32, j)] ~~> " + "reduce_sum(k, fun k0 -> A(bi * 32 + i, k0) *. B(k0, bj * " + "32 + j)), by := add_assoc_right(bk * 4, 1, 1)"); + } + __ghost_end(__ghost_pair_723); + __ghost(rewrite_linear, + "from := 1 + 1, to := 2, inside := fun (k: int) -> for j in " + "0..32 -> &s[MINDEX1(32, j)] ~~> reduce_sum(bk * 4 + k, fun " + "k0 -> A(bi * 32 + i, k0) *. B(k0, bj * 32 + j))"); + const __ghost_fn __ghost_pair_724 = + __ghost_begin(ro_group_focus, + "i := 2, items := fun (k: int) -> for j in 0..32 " + "-> &bT[MINDEX4(32, 256, 4, 32, bj, bk, k, j)] ~~> " + "B(bk * 4 + k, bj * 32 + j)"); +#pragma omp simd + for (int j = 0; j < 32; j++) { + __strict(); + __sreads("a ~> Matrix2(1024, 1024, A)"); + __xconsumes( + "&s[MINDEX1(32, j)] ~~> reduce_sum(bk * 4 + 2, fun k0 -> A(bi " + "* 32 + i, k0) *. B(k0, bj * 32 + j))"); + __xproduces( + "&s[MINDEX1(32, j)] ~~> reduce_sum(bk * 4 + (2 + 1), fun k0 -> " + "A(bi * 32 + i, k0) *. B(k0, bj * 32 + j))"); + __xreads( + "&bT[MINDEX4(32, 256, 4, 32, bj, bk, 2, j)] ~~> B(bk * 4 + 2, " + "bj * 32 + j)"); + __ghost(tiled_index_in_range, + "tile_index := bj, index := j, div_check := " + "tile_div_check_j51222", + ""); + __ghost(assert_prop, "P := (1024 = 256 * 4)", + "tile_div_check_k1320 <- proof"); + __ghost(tiled_index_in_range, + "tile_index := bk, index := 2, div_check := " + "tile_div_check_k1320", + ""); + const __ghost_fn __ghost_pair_2 = + __ghost_begin(ro_matrix2_focus, + "matrix := a, i := bi * 32 + i, j := bk * 4 + 2"); + s[MINDEX1(32, j)] += + a[MINDEX2(1024, 1024, bi * 32 + i, bk * 4 + 2)] * + bT[MINDEX4(32, 256, 4, 32, bj, bk, 2, j)]; + __ghost_end(__ghost_pair_2); + __ghost(in_range_bounds, "x := bk * 4 + 2", + "k_ge_021 <- lower_bound, #_23 <- upper_bound"); + __ghost(rewrite_float_linear, + "inside := fun v -> &s[MINDEX1(32, j)] ~~> v, by := " + "reduce_sum_add_right(bk * 4 + 2, fun k -> A(bi * 32 + i, " + "k) *. B(k, bj * 32 + j), k_ge_021)"); + __ghost(rewrite_linear, + "inside := fun (k: int) -> &s[MINDEX1(32, j)] ~~> " + "reduce_sum(k, fun k0 -> A(bi * 32 + i, k0) *. B(k0, bj * " + "32 + j)), by := add_assoc_right(bk * 4, 2, 1)"); + } + __ghost_end(__ghost_pair_724); + __ghost(rewrite_linear, + "from := 2 + 1, to := 3, inside := fun (k: int) -> for j in " + "0..32 -> &s[MINDEX1(32, j)] ~~> reduce_sum(bk * 4 + k, fun " + "k0 -> A(bi * 32 + i, k0) *. B(k0, bj * 32 + j))"); + const __ghost_fn __ghost_pair_725 = + __ghost_begin(ro_group_focus, + "i := 3, items := fun (k: int) -> for j in 0..32 " + "-> &bT[MINDEX4(32, 256, 4, 32, bj, bk, k, j)] ~~> " + "B(bk * 4 + k, bj * 32 + j)"); +#pragma omp simd + for (int j = 0; j < 32; j++) { + __strict(); + __sreads("a ~> Matrix2(1024, 1024, A)"); + __xconsumes( + "&s[MINDEX1(32, j)] ~~> reduce_sum(bk * 4 + 3, fun k0 -> A(bi " + "* 32 + i, k0) *. B(k0, bj * 32 + j))"); + __xproduces( + "&s[MINDEX1(32, j)] ~~> reduce_sum(bk * 4 + (3 + 1), fun k0 -> " + "A(bi * 32 + i, k0) *. B(k0, bj * 32 + j))"); + __xreads( + "&bT[MINDEX4(32, 256, 4, 32, bj, bk, 3, j)] ~~> B(bk * 4 + 3, " + "bj * 32 + j)"); + __ghost(tiled_index_in_range, + "tile_index := bj, index := j, div_check := " + "tile_div_check_j51222", + ""); + __ghost(assert_prop, "P := (1024 = 256 * 4)", + "tile_div_check_k1320 <- proof"); + __ghost(tiled_index_in_range, + "tile_index := bk, index := 3, div_check := " + "tile_div_check_k1320", + ""); + const __ghost_fn __ghost_pair_2 = + __ghost_begin(ro_matrix2_focus, + "matrix := a, i := bi * 32 + i, j := bk * 4 + 3"); + s[MINDEX1(32, j)] += + a[MINDEX2(1024, 1024, bi * 32 + i, bk * 4 + 3)] * + bT[MINDEX4(32, 256, 4, 32, bj, bk, 3, j)]; + __ghost_end(__ghost_pair_2); + __ghost(in_range_bounds, "x := bk * 4 + 3", + "k_ge_021 <- lower_bound, #_23 <- upper_bound"); + __ghost(rewrite_float_linear, + "inside := fun v -> &s[MINDEX1(32, j)] ~~> v, by := " + "reduce_sum_add_right(bk * 4 + 3, fun k -> A(bi * 32 + i, " + "k) *. B(k, bj * 32 + j), k_ge_021)"); + __ghost(rewrite_linear, + "inside := fun (k: int) -> &s[MINDEX1(32, j)] ~~> " + "reduce_sum(k, fun k0 -> A(bi * 32 + i, k0) *. B(k0, bj * " + "32 + j)), by := add_assoc_right(bk * 4, 3, 1)"); + } + __ghost_end(__ghost_pair_725); + __ghost(rewrite_linear, + "from := 3 + 1, to := 4, inside := fun (k: int) -> for j in " + "0..32 -> &s[MINDEX1(32, j)] ~~> reduce_sum(bk * 4 + k, fun " + "k0 -> A(bi * 32 + i, k0) *. B(k0, bj * 32 + j))"); + __ghost( + mindex2_unfold, + "H := fun (access: int * int -> float*) -> for j in 0..32 -> " + "access(i, j) ~> UninitCell, matrix := sum, n1 := 32, n2 := 32"); + MATRIX1_COPY_float(&sum[i * 32], s, 32); + __ghost(mindex2_fold, + "H := fun (access: int * int -> float*) -> for j in 0..32 -> " + "access(i, j) ~~> reduce_sum(bk * 4 + 4, fun k0 -> A(bi * 32 " + "+ i, k0) *. B(k0, bj * 32 + j)), matrix := sum, n1 := 32, " + "n2 := 32"); + for (int j = 0; j < 32; j++) { + __strict(); + __xconsumes( + "&sum[MINDEX2(32, 32, i, j)] ~~> reduce_sum(bk * 4 + 4, fun k0 " + "-> A(bi * 32 + i, k0) *. B(k0, bj * 32 + j))"); + __xproduces( + "&sum[MINDEX2(32, 32, i, j)] ~~> reduce_sum((bk + 1) * 4, fun " + "k0 -> A(bi * 32 + i, k0) *. B(k0, bj * 32 + j))"); + __ghost(rewrite_linear, + "inside := fun (k: int) -> &sum[MINDEX2(32, 32, i, j)] ~~> " + "reduce_sum(k, fun k0 -> A(bi * 32 + i, k0) *. B(k0, bj * " + "32 + j)), by := mul_add_factor(bk, 4)"); + } + } + } + for (int i = 0; i < 32; i++) { + __strict(); + __xconsumes( + "for j in 0..32 -> &sum[MINDEX2(32, 32, i, j)] ~~> reduce_sum(256 " + "* 4, fun k0 -> A(bi * 32 + i, k0) *. B(k0, bj * 32 + j))"); + __xproduces( + "for _v11 in 0..32 -> &sum[MINDEX2(32, 32, i, _v11)] ~> " + "UninitCell"); + __xwrites( + "for j in 0..32 -> &c[MINDEX2(1024, 1024, bi * 32 + i, bj * 32 + " + "j)] ~~> matmul(A, B, 1024)(bi * 32 + i, bj * 32 + j)"); + for (int j = 0; j < 32; j++) { + __strict(); + __xconsumes( + "&sum[MINDEX2(32, 32, i, j)] ~~> reduce_sum(256 * 4, fun k0 -> " + "A(bi * 32 + i, k0) *. B(k0, bj * 32 + j))"); + __xproduces("&sum[MINDEX2(32, 32, i, j)] ~> UninitCell"); + __xwrites( + "&c[MINDEX2(1024, 1024, bi * 32 + i, bj * 32 + j)] ~~> matmul(A, " + "B, 1024)(bi * 32 + i, bj * 32 + j)"); + __ghost(assert_prop, "P := (1024 = 256 * 4)", + "tile_div_check_k12 <- proof"); + __ghost(rewrite_linear, + "inside := fun (k: int) -> &sum[MINDEX2(32, 32, i, j)] ~~> " + "reduce_sum(k, fun k0 -> A(bi * 32 + i, k0) *. B(k0, bj * 32 " + "+ j)), by := eq_sym(1024, 256 * 4, tile_div_check_k12)"); + c[MINDEX2(1024, 1024, bi * 32 + i, bj * 32 + j)] = + sum[MINDEX2(32, 32, i, j)]; + } + } + free(sum); + } + __ghost( + swap_groups, + "outer_range := 0..32, inner_range := 0..32, items := fun (bj: int) " + "(i: int) -> for j in 0..32 -> &c[MINDEX2(1024, 1024, bi * 32 + i, bj " + "* 32 + j)] ~~> matmul(A, B, 1024)(bi * 32 + i, bj * 32 + j)"); + for (int i = 0; i < 32; i++) { + __strict(); + __xconsumes( + "for bj in 0..32 -> for j in 0..32 -> &c[MINDEX2(1024, 1024, bi * 32 " + "+ i, bj * 32 + j)] ~~> reduce_sum(1024, fun k -> A(bi * 32 + i, k) " + "*. B(k, bj * 32 + j))"); + __xproduces( + "for j in 0..1024 -> &c[MINDEX2(1024, 1024, bi * 32 + i, j)] ~~> " + "matmul(A, B, 1024)(bi * 32 + i, j)"); + __ghost(assert_prop, "P := (1024 = 32 * 32)", + "tile_div_check_j510 <- proof"); + __ghost(untile_divides, + "div_check := tile_div_check_j510, items := fun (j: int) -> " + "&c[MINDEX2(1024, 1024, bi * 32 + i, j)] ~~> matmul(A, B, " + "1024)(bi * 32 + i, j)"); + } + } + free(bT); + __ghost( + untile_divides, + "div_check := tile_div_check_i, items := fun (i: int) -> for j in " + "0..1024 -> &c[MINDEX2(1024, 1024, i, j)] ~~> matmul(A, B, 1024)(i, j)"); +} diff --git a/case_studies/opencv/box_filter_rowsum_models.ml b/case_studies/opencv/box_filter_rowsum_models.ml index a9014e393..a3fad0e92 100644 --- a/case_studies/opencv/box_filter_rowsum_models.ml +++ b/case_studies/opencv/box_filter_rowsum_models.ml @@ -42,7 +42,7 @@ let _ = Run.script_cpp (fun () -> + Instr.gather_targets + Variable.symb_eval *) - !! Loop.collapse [nbMulti; cMark "w"; cFor "i"]; + !! Loop.collapse ~simpl:Arith.no_simpl [nbMulti; cMark "w"; cFor "i"]; !! Loop.swap [nbMulti; cMark "anyw"; cFor "i"]; !! Reduce.first_then_slide ~mark_alloc:"acc" [nbMulti; cMark "anyw"; cFor "i"]; @@ -52,7 +52,7 @@ let _ = Run.script_cpp (fun () -> !! Specialize.variable_multi ~mark_then:fst ~mark_else:"anycn" ~simpl:Arith.no_simpl ["cn", int 1; "cn", int 3; "cn", int 4] [cMark "anyw"; cFor "c"]; - !! Loop.unroll [nbMulti; cMark "cn"; cFor "c"]; + !! Loop.unroll ~simpl:Arith.no_simpl [nbMulti; cMark "cn"; cFor "c"]; !! Target.foreach [nbMulti; cMark "cn"] (fun c -> Loop.fusion_targets ~into:FuseIntoLast [nbMulti; c; cFor "i"]; diff --git a/lib/framework/c/ast_to_c.ml b/lib/framework/c/ast_to_c.ml index 2e98d0e7f..9e838bb29 100644 --- a/lib/framework/c/ast_to_c.ml +++ b/lib/framework/c/ast_to_c.ml @@ -423,7 +423,7 @@ and binop_to_doc style ?(formula: bool = false) (op : binary_op) : document = | Binop_array_access -> lbracket ^^ rbracket | Binop_array_get -> lbracket ^^ rbracket | Binop_eq -> if formula then equals else twice equals - | Binop_neq -> bang ^^ equals + | Binop_neq -> if formula then string "<>" else bang ^^ equals | Binop_sub -> minus | Binop_add -> plus | Binop_mul -> star @@ -1039,11 +1039,11 @@ and apps_to_doc style ?(prec : int = 0) ~(annot: trm_annot) ~(print_struct_init_ begin match op with (* | Unop_get when style.optitrust_syntax -> star ^^ d *) | Unop_get -> star ^^ d - | Unop_address ->ampersand ^^ d + | Unop_address -> ampersand ^^ d | Unop_neg -> bang ^^ d | Unop_bitwise_neg -> tilde ^^ d - | Unop_minus -> minus ^^ float_mod ^^ blank 1 ^^ d - | Unop_plus -> plus ^^ float_mod ^^ blank 1 ^^ d + | Unop_minus -> lparen ^^ minus ^^ float_mod ^^ blank 1 ^^ d ^^ rparen + | Unop_plus -> lparen ^^ plus ^^ float_mod ^^ blank 1 ^^ d ^^ rparen | Unop_post_incr -> d ^^ twice plus | Unop_post_decr -> d ^^ twice minus | Unop_pre_incr -> twice plus ^^ d diff --git a/lib/framework/prelude.ml b/lib/framework/prelude.ml index b99e7d483..551e08f9f 100644 --- a/lib/framework/prelude.ml +++ b/lib/framework/prelude.ml @@ -35,7 +35,7 @@ let find_var_filter ?(target : target = []) (filter : var -> bool) : var * typ o then find_var_filter_on candidates filter (skip_includes (Trace.ast ())) else List.iter (fun p -> find_var_filter_on candidates filter (Target.resolve_path p) - ) (resolve_target_with_stringreprs_available target (Trace.ast ())); + ) (resolve_target target); (* let candidates = Var_set.filter filter vars in *) match Var_map.cardinal !candidates with | 0 -> failwith "could not find variable in current AST variables" (* ": %s" (vars_to_string (Var_set.elements vars)) *) diff --git a/lib/framework/runtime/trace.ml b/lib/framework/runtime/trace.ml index 3ea5e8e7e..4760199d6 100644 --- a/lib/framework/runtime/trace.ml +++ b/lib/framework/runtime/trace.ml @@ -981,8 +981,15 @@ let rec finalize_step ~(on_error: bool) (step : step_tree) : unit = if not (is_kind_preserving_code step.step_kind) then make_substeps_chained step; (* Check that [Flags.check_validity] is like at the start of the step *) - if not on_error && (!Flags.typechecking_mode <> infos.step_typechecking_mode) (* (!Flags.check_validity && (not !Flags.use_resources_with_models)) <> infos.step_flag_check_validity *) - then raise (TraceFailure "At finalize_step, Flags.check_validity is not same as when step was opened."); + (* if not on_error && (!Flags.check_validity && (not !Flags.use_resources_with_models)) <> infos.step_flag_check_validity *) + begin match (on_error, infos.step_typechecking_mode, !Flags.typechecking_mode) with + | true, _, _ -> () + | false, _, Unverified -> () + | false, Unverified, _ -> + raise (TraceFailure "At finalize_step, Flags.typechecking_mode change from Unverified to something else."); + | false, Annotated, (Annotated | AnnotatedAndVerified) -> () + | false, AnnotatedAndVerified, (Annotated | AnnotatedAndVerified) -> () + end; (* Set the validity flag if it is not already set, in particular if the step is an identity step, or if all substeps are valid. (they have previously been ensured to form a chain). diff --git a/lib/transfo/accesses_basic.ml b/lib/transfo/accesses_basic.ml index 5b681a14b..6908e15a2 100644 --- a/lib/transfo/accesses_basic.ml +++ b/lib/transfo/accesses_basic.ml @@ -3,7 +3,7 @@ open Target (* DEBUG flags *) -let debug_transform = true +let debug_transform = false type transform_ret = { typedvar : (var * typ option) option ref; @@ -213,6 +213,7 @@ let%transfo transform (f_get : trm -> trm) (f_set : trm -> trm) ?(mark_to_prove : mark = no_mark) ?(mark_preprocess : mark = no_mark) ?(mark_postprocess : mark = no_mark) (tg : target) : unit = + Resources.required_for_check (); Marks.with_marks (fun next_mark -> Target.iter (fun p -> let (p_seq, span) = Path.extract_last_dir_span p in let (mark_to_prove, mark_preprocess, mark_postprocess, mark_handled_resources) = diff --git a/lib/transfo/arith.ml b/lib/transfo/arith.ml index 034ab4e35..20e9b6a4b 100644 --- a/lib/transfo/arith.ml +++ b/lib/transfo/arith.ml @@ -65,7 +65,11 @@ let arith_goal_solver ((x, formula): resource_item) (evar_ctx: Resource_computat Pattern.(trm_apps2 (trm_specific_var var_is_subrange) (formula_range !__ !__ !__) (formula_range !__ !__ !__)) (fun sub_start sub_stop sub_step start stop step () -> Arith_core.(check_geq sub_start start && check_leq sub_stop stop && check_eq (trm_trunc_mod_int sub_step step) (trm_int 0)) ); - Pattern.(formula_is_true (trm_eq !__ !__)) (fun t1 t2 () -> check_eq t1 t2); + Pattern.(formula_is_true (trm_eq !__ !__)) (fun t1 t2 () -> + (* FIXME: built-in syntactic eq (refl) solving in typechecker outside of arith ? + could also accept triggering variable unifications. *) + if are_same_trm t1 t2 then true else check_eq t1 t2 + ); Pattern.(formula_is_true (trm_neq !__ !__)) (fun t1 t2 () -> check_neq t1 t2); Pattern.(formula_is_true (trm_gt !__ !__)) (fun t1 t2 () -> check_gt t1 t2); Pattern.(formula_is_true (trm_ge !__ !__)) (fun t1 t2 () -> check_geq t1 t2); diff --git a/lib/transfo/cleanup.ml b/lib/transfo/cleanup.ml index a2454dcd5..18d277951 100644 --- a/lib/transfo/cleanup.ml +++ b/lib/transfo/cleanup.ml @@ -12,6 +12,7 @@ let%transfo std ?(arith_simpl : (Arith.expr -> Arith.expr) list = [Arith.gather_ (* should: this be a transfo instead of trm -> trm ? *) (* Matrix.elim_mops ~simpl:(Arith_core.(simplify false Arith_basic.(compose [expand; euclidian; gather_rec; compute]))) []; *) Matrix.elim_mops ~simpl:(fun t -> t) []; + Flags.typechecking_mode := Flags.Unverified; Arith.(simpl_rec expand_rec) []; Arith.(simpl_rec (compose [euclidian; compute])) []; Arith.(simpl_rec gather_rec) []; diff --git a/lib/transfo/instr.ml b/lib/transfo/instr.ml index dafc4c609..3c0020e7d 100644 --- a/lib/transfo/instr.ml +++ b/lib/transfo/instr.ml @@ -193,7 +193,8 @@ let%transfo gather_targets ?(dest : gather_dest = GatherAtLast) (tg : target) : span else match Trace.step_backtrack_on_failure (fun () -> - Instr_basic.move ~dest:[dAfter span.stop] (tg_span span) + Instr_basic.move ~dest:[dAfter span.stop] (tg_span span); + Resources.ensure_computed (); ) with | Success () -> move_downwards_with_deps { start = span.start + 1; stop = span.stop + 1 } dest @@ -208,7 +209,8 @@ let%transfo gather_targets ?(dest : gather_dest = GatherAtLast) (tg : target) : span else match Trace.step_backtrack_on_failure (fun () -> - Instr_basic.move ~dest:[dBefore (span.start - 1)] (tg_span span) + Instr_basic.move ~dest:[dBefore (span.start - 1)] (tg_span span); + Resources.ensure_computed (); ) with | Success () -> move_upwards_with_deps { start = span.start - 1; stop = span.stop - 1 } dest diff --git a/lib/transfo/loop.ml b/lib/transfo/loop.ml index 7668a43b2..bd5a25cf3 100644 --- a/lib/transfo/loop.ml +++ b/lib/transfo/loop.ml @@ -750,6 +750,7 @@ let%transfo fusion_targets ?(into : fuse_into = FuseIntoFirst) ?(nest_of : int = (* TODO: add flag to only allow backtrack for ghosts instead of all instrs? *) match Trace.step_backtrack_on_failure (fun () -> Instr_basic.move ~dest:[tBefore; cMark (snd to_fuse)] (target_of_path (p_seq @ [Path.Dir_seq_nth i])); + Resources.ensure_computed (); ) with | Success () -> () | Failure _ -> incr not_before_current; @@ -775,6 +776,7 @@ let%transfo fusion_targets ?(into : fuse_into = FuseIntoFirst) ?(nest_of : int = for i = span_end downto span_beg do match Trace.step_backtrack_on_failure (fun () -> Instr_basic.move ~dest:[tAfter; cMark (snd to_fuse)] (target_of_path (p_seq @ [Path.Dir_seq_nth i])); + Resources.ensure_computed (); ) with | Success () -> () | Failure _ -> incr not_after_current; diff --git a/lib/transfo/loop_basic.ml b/lib/transfo/loop_basic.ml index ef343e526..ffdf282b0 100644 --- a/lib/transfo/loop_basic.ml +++ b/lib/transfo/loop_basic.ml @@ -616,7 +616,7 @@ let%transfo fusion ?(upwards : bool = true) (tg : target) : unit = let (index, p_seq) = Path.index_in_seq p in Resources.required_for_check (); Target.apply_at_path (fusion_on index upwards) p_seq; - Resources.required_for_check (); + (* Resources.required_for_check (); *) ) tg; Resources.justif_correct "loop resources where successfully merged" diff --git a/lib/transfo/loop_core.ml b/lib/transfo/loop_core.ml index 28d9ec5b0..c4ef459cb 100644 --- a/lib/transfo/loop_core.ml +++ b/lib/transfo/loop_core.ml @@ -78,7 +78,8 @@ let tile_on (tile_index : string) (bound : tile_bound) (tile_size : trm) (t : tr let outer_range = { index = tile_index; start = (trm_int 0); direction = DirUp; stop = tile_count; step = trm_step_one () } in let inner_range = { index; start = (trm_int 0); direction = DirUp; stop = tile_size; step = trm_step_one () } in - if not contract.strict then begin + if Flags.unverified () then begin + (* if not (contract.strict) *) (* if !Flags.check_validity then begin Trace.justif "loop range is checked to be dividable by tile size"; trm_seq_nobrace_nomarks [ @@ -348,7 +349,7 @@ let unroll_on (inner_braces : bool) (outer_seq_with_mark : mark) (subst_mark : m else trm_seq_nobrace_nomarks unrolled_body in - if not contract.strict then + if Flags.unverified () then outer_seq else let unroll_in_range_ghosts = List.map (fun new_index -> diff --git a/lib/transfo/variable_core.ml b/lib/transfo/variable_core.ml index 0a5d28750..cce2f9875 100644 --- a/lib/transfo/variable_core.ml +++ b/lib/transfo/variable_core.ml @@ -46,7 +46,7 @@ let init_detach_on (t : trm) : trm = | Some init -> init | _ -> trm_fail t "init_detach_on: can't detach an uninitialized or constant declaration" in - let var_decl = trm_let_mut_uninit ~annot:t.annot (x, Option.unsome ~error:"expected init type" init.typ) in + let var_decl = trm_let_mut_uninit ~annot:t.annot (x, Option.unsome ~error:"expected init type" (typ_ptr_inv tx)) in (* Check if variable was declared as a reference *) let var_assgn = trm_set (trm_var ~typ:tx x) init in trm_seq_nobrace_nomarks [var_decl; var_assgn] From 43ef302238fa52a2e0e73b16dd58240c451542fa Mon Sep 17 00:00:00 2001 From: Thomas Koehler Date: Wed, 29 Jul 2026 13:38:38 +0200 Subject: [PATCH 22/23] disable unsound sreads rule for GPU thread fors, replace with a sound but less practical one, fix tests, case studies TBD --- case_studies/gpu/transpose/transpose.ml | 2 +- case_studies/gpu/transpose/transpose_exp.cpp | 12 +-- case_studies/gpu/vector_add/vector_add.ml | 4 +- lib/framework/resources/resource_contract.ml | 29 +++--- .../scale/accesses_scale_basic_exp.cpp | 2 +- tests/ast/c_address_exp.cpp | 10 +- tests/ast/c_features_exp.cpp | 10 +- tests/ast/c_infix_exp.cpp | 10 +- tests/ast/c_stackvar_exp.cpp | 10 +- tests/expr/replace/expr_replace_exp.cpp | 2 +- .../expr_replace_fun_basic_exp.cpp | 2 +- .../dps_call/function_dps_call_exp.cpp | 8 +- .../dps_def/function_dps_def_doc_exp.cpp | 4 +- .../function/dps_def/function_dps_def_exp.cpp | 8 +- .../function_use_infix_ops_exp.cpp | 4 +- tests/gpu/thread_for_test.cpp | 69 +++++++++++++- tests/gpu/thread_for_test.ml | 7 +- tests/gpu/thread_for_test_exp.cpp | 91 ++++++++++++++++++- tests/gpu/thread_for_test_exp.cu | 52 +++++++---- .../extend_range/loop_extend_range_exp.cpp | 2 +- .../loop_shift_range_basic_doc_exp.cpp | 2 +- tests/loop/tile/loop_tile.ml | 16 ++-- tests/loop/tile/loop_tile_doc.ml | 2 + tests/loop/unroll/loop_unroll.ml | 7 +- tests/loop/unroll/loop_unroll_basic_doc.ml | 2 +- tests/loop/unroll/loop_unroll_doc.ml | 2 + tests/loop/unroll/loop_unroll_exp.cpp | 26 +++--- tests/resources/contracts/loop_mode_check.ml | 2 +- .../elim_instr/sequence_elim_instr.ml | 2 +- .../local_name/variable_local_name.ml | 4 +- .../local_name/variable_local_name_exp.cpp | 6 +- tests/variable/rename/variable_rename_exp.cpp | 2 +- .../variable/renames/variable_renames_exp.cpp | 2 +- 33 files changed, 291 insertions(+), 122 deletions(-) diff --git a/case_studies/gpu/transpose/transpose.ml b/case_studies/gpu/transpose/transpose.ml index 0e0c1e172..2454571a5 100644 --- a/case_studies/gpu/transpose/transpose.ml +++ b/case_studies/gpu/transpose/transpose.ml @@ -3,7 +3,7 @@ open Prelude (* let _ = Flags.check_validity := true *) let _ = Flags.typechecking_mode := Flags.AnnotatedAndVerified -let _ = Flags.recompute_resources_between_steps := false +(* let _ = Flags.recompute_resources_between_steps := false *) let _ = Flags.disable_stringreprs := true let _ = Flags.save_ast_for_steps := None (* Some Flags.Steps_important *) let _ = Flags.pretty_matrix_notation := false diff --git a/case_studies/gpu/transpose/transpose_exp.cpp b/case_studies/gpu/transpose/transpose_exp.cpp index a68837d60..8465005b1 100644 --- a/case_studies/gpu/transpose/transpose_exp.cpp +++ b/case_studies/gpu/transpose/transpose_exp.cpp @@ -28,17 +28,17 @@ void transpose(float* a, float* b, int W, int H) { "div_check := tile_div_check_x, items := fun (x: int) -> for y in " "0..H -> &d_b[MINDEX2(W, H, x, y)] ~> UninitCellOf(GMem)"); /*@kernel_sequence*/ { - kernel_launch(MSIZE2(exact_div(H, 32), exact_div(W, 32)), MSIZE2(16, 32), - sizeof(float) * (32 * 32) + 0); __ghost(assume, - "P := (exact_div(H, 32) * (exact_div(W, 32)) = MSIZE2(exact_div(H, " - "32), exact_div(W, 32)))"); + "P := (MSIZE2(exact_div(H, 32), exact_div(W, 32)) = exact_div(H, " + "32) * (exact_div(W, 32)))"); __ghost(assume, "P := (MSIZE2(exact_div(H, 32), exact_div(W, 32)) * MSIZE2(16, 32) " "= MSIZE4(exact_div(H, 32), exact_div(W, 32), 16, 32))"); __ghost(assume, - "P := (MSIZE2(exact_div(H, 32), exact_div(W, 32)) = exact_div(H, " - "32) * (exact_div(W, 32)))"); + "P := (exact_div(H, 32) * (exact_div(W, 32)) = MSIZE2(exact_div(H, " + "32), exact_div(W, 32)))"); + kernel_launch(MSIZE2(exact_div(H, 32), exact_div(W, 32)), MSIZE2(16, 32), + sizeof(float) * (32 * 32) + 0); __ghost(take_smem_token, "tok_sz := sizeof(float) * (32 * 32)"); for (int bx = 0; bx < exact_div(W, 32); bx++) { __strict(); diff --git a/case_studies/gpu/vector_add/vector_add.ml b/case_studies/gpu/vector_add/vector_add.ml index 1e71e5f69..79f8589dc 100644 --- a/case_studies/gpu/vector_add/vector_add.ml +++ b/case_studies/gpu/vector_add/vector_add.ml @@ -4,8 +4,8 @@ open Cuda_lowering (* let _ = Flags.check_validity := true *) let _ = Flags.typechecking_mode := Flags.AnnotatedAndVerified -let _ = Flags.pretty_matrix_notation := true -let _ = Flags.recompute_resources_between_steps := false +let _ = Flags.pretty_matrix_notation := false +(* let _ = Flags.recompute_resources_between_steps := false *) let _ = Flags.disable_stringreprs := true let _ = Flags.save_ast_for_steps := Some Flags.Steps_important diff --git a/lib/framework/resources/resource_contract.ml b/lib/framework/resources/resource_contract.ml index 55321c47c..6e673d8bc 100644 --- a/lib/framework/resources/resource_contract.ml +++ b/lib/framework/resources/resource_contract.ml @@ -293,32 +293,33 @@ let [@warning "-11"] get_loop_contract_generators res loop_mode range contract: | GpuThread -> Some (compute_thread_for_ctx_ranges range res) | _ -> None in - let grp_apply_fn = match threadfor_info with - | Some info -> - (* TODO: should the pre & post share the threadsctx variable or no? *) - let tctx = (new_anon_hyp (),formula_threadsctx info.r_out) in - fun range res -> ( - let res = Resource_set.desyncgroup_range range res in - { res with linear = tctx :: res.linear } - ) - | _ -> - (match loop_mode with - | MagicThread -> Resource_set.desyncgroup_range - | _ -> Resource_set.group_range) in + let par_reads_inside = parallel_reads_inside_loop range contract.parallel_reads in let contract_outside_loop () = + let grp_apply_fn = match threadfor_info with + | Some info -> + (* TODO: should the pre & post share the threadsctx variable or no? *) + let tctx = (new_anon_hyp (),formula_threadsctx info.r_out) in + fun range res -> ( + Resource_set.add_linear tctx (Resource_set.desyncgroup_range range res) + ) + | _ -> + (match loop_mode with + | MagicThread -> Resource_set.desyncgroup_range + | _ -> Resource_set.group_range) in let invariant_before = Resource_set.subst_loop_range_start range contract.invariant in let pre = grp_apply_fn range contract.iter_contract.pre in let pre = Resource_set.union invariant_before (Resource_set.add_linear_list contract.parallel_reads pre) in let pre = { pre with pure = contract.loop_ghosts @ pre.pure } in let invariant_after = Resource_set.subst_loop_range_end range contract.invariant in let post = grp_apply_fn range contract.iter_contract.post in - let post = Resource_set.add_linear_list contract.parallel_reads post in + let post = match loop_mode with + | Sequential | Parallel -> Resource_set.add_linear_list contract.parallel_reads post + | GpuThread | MagicThread -> Resource_set.union (Resource_set.desyncgroup_range range (Resource_set.make ~linear:par_reads_inside ())) post in let post = Resource_set.union invariant_after post in { pre; post } in let contract_inside_loop () = - let par_reads_inside = parallel_reads_inside_loop range contract.parallel_reads in let pre = Resource_set.union contract.invariant (Resource_set.add_linear_list par_reads_inside contract.iter_contract.pre) in let index_in_range_hyp = (new_anon_hyp (), formula_in_range (trm_var range.index) (formula_loop_range range)) in let pre = { pre with pure = (range.index, typ_int) :: index_in_range_hyp :: contract.loop_ghosts @ pre.pure } in diff --git a/tests/accesses/scale/accesses_scale_basic_exp.cpp b/tests/accesses/scale/accesses_scale_basic_exp.cpp index 44e51105e..c28ab1fa5 100644 --- a/tests/accesses/scale/accesses_scale_basic_exp.cpp +++ b/tests/accesses/scale/accesses_scale_basic_exp.cpp @@ -4,7 +4,7 @@ void f() { double t[3] = {1., 2., 3.}; double v; v = 2.; - __ghost(to_prove, "P := (0.5 !=. 0)"); + __ghost(to_prove, "P := (0.5 <>. 0)"); const double u = 1. * 0.5; int i = 0; t[i] = t[i] + v * (u / 0.5); diff --git a/tests/ast/c_address_exp.cpp b/tests/ast/c_address_exp.cpp index f86dce17c..ed45558e8 100644 --- a/tests/ast/c_address_exp.cpp +++ b/tests/ast/c_address_exp.cpp @@ -187,7 +187,7 @@ void bag_ho_iter_chunk(bag* b, void (*body)(particle*)) { void bag_push_initial(bag* b, particle p) { bag_push_serial(b, p); } -void bag_init_initial(bag* b) { bag_init(b, -1, -1); } +void bag_init_initial(bag* b) { bag_init(b, (-1), (-1)); } unsigned int FREELIST_SIZE; @@ -223,7 +223,7 @@ void manual_chunk_free(chunk* c, int thread_id) { } } -const int THREAD_INITIAL = -1; +const int THREAD_INITIAL = (-1); const int THREAD_ZERO = 0; @@ -423,9 +423,9 @@ double_nbCorners cornerInterpolationCoeff(vect pos) { const double rX = relativePosX((pos.x)); const double rY = relativePosY((pos.y)); const double rZ = relativePosZ((pos.z)); - const double cX = 1. + -1. * rX; - const double cY = 1. + -1. * rY; - const double cZ = 1. + -1. * rZ; + const double cX = 1. + (-1.) * rX; + const double cY = 1. + (-1.) * rY; + const double cZ = 1. + (-1.) * rZ; double_nbCorners r; (r.v)[0] = cX * cY * cZ; (r.v)[1] = cX * cY * rZ; diff --git a/tests/ast/c_features_exp.cpp b/tests/ast/c_features_exp.cpp index f86dce17c..ed45558e8 100644 --- a/tests/ast/c_features_exp.cpp +++ b/tests/ast/c_features_exp.cpp @@ -187,7 +187,7 @@ void bag_ho_iter_chunk(bag* b, void (*body)(particle*)) { void bag_push_initial(bag* b, particle p) { bag_push_serial(b, p); } -void bag_init_initial(bag* b) { bag_init(b, -1, -1); } +void bag_init_initial(bag* b) { bag_init(b, (-1), (-1)); } unsigned int FREELIST_SIZE; @@ -223,7 +223,7 @@ void manual_chunk_free(chunk* c, int thread_id) { } } -const int THREAD_INITIAL = -1; +const int THREAD_INITIAL = (-1); const int THREAD_ZERO = 0; @@ -423,9 +423,9 @@ double_nbCorners cornerInterpolationCoeff(vect pos) { const double rX = relativePosX((pos.x)); const double rY = relativePosY((pos.y)); const double rZ = relativePosZ((pos.z)); - const double cX = 1. + -1. * rX; - const double cY = 1. + -1. * rY; - const double cZ = 1. + -1. * rZ; + const double cX = 1. + (-1.) * rX; + const double cY = 1. + (-1.) * rY; + const double cZ = 1. + (-1.) * rZ; double_nbCorners r; (r.v)[0] = cX * cY * cZ; (r.v)[1] = cX * cY * rZ; diff --git a/tests/ast/c_infix_exp.cpp b/tests/ast/c_infix_exp.cpp index f86dce17c..ed45558e8 100644 --- a/tests/ast/c_infix_exp.cpp +++ b/tests/ast/c_infix_exp.cpp @@ -187,7 +187,7 @@ void bag_ho_iter_chunk(bag* b, void (*body)(particle*)) { void bag_push_initial(bag* b, particle p) { bag_push_serial(b, p); } -void bag_init_initial(bag* b) { bag_init(b, -1, -1); } +void bag_init_initial(bag* b) { bag_init(b, (-1), (-1)); } unsigned int FREELIST_SIZE; @@ -223,7 +223,7 @@ void manual_chunk_free(chunk* c, int thread_id) { } } -const int THREAD_INITIAL = -1; +const int THREAD_INITIAL = (-1); const int THREAD_ZERO = 0; @@ -423,9 +423,9 @@ double_nbCorners cornerInterpolationCoeff(vect pos) { const double rX = relativePosX((pos.x)); const double rY = relativePosY((pos.y)); const double rZ = relativePosZ((pos.z)); - const double cX = 1. + -1. * rX; - const double cY = 1. + -1. * rY; - const double cZ = 1. + -1. * rZ; + const double cX = 1. + (-1.) * rX; + const double cY = 1. + (-1.) * rY; + const double cZ = 1. + (-1.) * rZ; double_nbCorners r; (r.v)[0] = cX * cY * cZ; (r.v)[1] = cX * cY * rZ; diff --git a/tests/ast/c_stackvar_exp.cpp b/tests/ast/c_stackvar_exp.cpp index f86dce17c..ed45558e8 100644 --- a/tests/ast/c_stackvar_exp.cpp +++ b/tests/ast/c_stackvar_exp.cpp @@ -187,7 +187,7 @@ void bag_ho_iter_chunk(bag* b, void (*body)(particle*)) { void bag_push_initial(bag* b, particle p) { bag_push_serial(b, p); } -void bag_init_initial(bag* b) { bag_init(b, -1, -1); } +void bag_init_initial(bag* b) { bag_init(b, (-1), (-1)); } unsigned int FREELIST_SIZE; @@ -223,7 +223,7 @@ void manual_chunk_free(chunk* c, int thread_id) { } } -const int THREAD_INITIAL = -1; +const int THREAD_INITIAL = (-1); const int THREAD_ZERO = 0; @@ -423,9 +423,9 @@ double_nbCorners cornerInterpolationCoeff(vect pos) { const double rX = relativePosX((pos.x)); const double rY = relativePosY((pos.y)); const double rZ = relativePosZ((pos.z)); - const double cX = 1. + -1. * rX; - const double cY = 1. + -1. * rY; - const double cZ = 1. + -1. * rZ; + const double cX = 1. + (-1.) * rX; + const double cY = 1. + (-1.) * rY; + const double cZ = 1. + (-1.) * rZ; double_nbCorners r; (r.v)[0] = cX * cY * cZ; (r.v)[1] = cX * cY * rZ; diff --git a/tests/expr/replace/expr_replace_exp.cpp b/tests/expr/replace/expr_replace_exp.cpp index 86265745a..2db6bb971 100644 --- a/tests/expr/replace/expr_replace_exp.cpp +++ b/tests/expr/replace/expr_replace_exp.cpp @@ -4,7 +4,7 @@ int f(int x) { } int f1(int x) { - int y = -1; + int y = (-1); return y + x; } diff --git a/tests/expr/replace_fun/expr_replace_fun_basic_exp.cpp b/tests/expr/replace_fun/expr_replace_fun_basic_exp.cpp index 4ce93cbf9..a5ec98ed2 100644 --- a/tests/expr/replace_fun/expr_replace_fun_basic_exp.cpp +++ b/tests/expr/replace_fun/expr_replace_fun_basic_exp.cpp @@ -4,7 +4,7 @@ int f(int x) { } int f1(int x) { - int y = -1; + int y = (-1); return y + x; } diff --git a/tests/function/dps_call/function_dps_call_exp.cpp b/tests/function/dps_call/function_dps_call_exp.cpp index e828441bc..71b12502e 100644 --- a/tests/function/dps_call/function_dps_call_exp.cpp +++ b/tests/function/dps_call/function_dps_call_exp.cpp @@ -2,7 +2,7 @@ int f(int x) { if (x > 0) { return x; } else { - return -x; + return (-x); } } @@ -10,7 +10,7 @@ void f_dps(int x, int* res) { if (x > 0) { *res = x; } else { - *res = -x; + *res = (-x); } } @@ -18,7 +18,7 @@ int g(int x, int y) { if (x > 0) { return x + y; } else { - return -x + y; + return (-x) + y; } } @@ -26,7 +26,7 @@ void g_dps(int x, int y, int* res) { if (x > 0) { *res = x + y; } else { - *res = -x + y; + *res = (-x) + y; } } diff --git a/tests/function/dps_def/function_dps_def_doc_exp.cpp b/tests/function/dps_def/function_dps_def_doc_exp.cpp index 6e967303b..11b318bd5 100644 --- a/tests/function/dps_def/function_dps_def_doc_exp.cpp +++ b/tests/function/dps_def/function_dps_def_doc_exp.cpp @@ -2,7 +2,7 @@ int f(int x) { if (x > 0) { return x; } else { - return -x; + return (-x); } } @@ -10,6 +10,6 @@ void f_dps(int x, int* res) { if (x > 0) { *res = x; } else { - *res = -x; + *res = (-x); } } diff --git a/tests/function/dps_def/function_dps_def_exp.cpp b/tests/function/dps_def/function_dps_def_exp.cpp index a249d4093..1d0c2f8b2 100644 --- a/tests/function/dps_def/function_dps_def_exp.cpp +++ b/tests/function/dps_def/function_dps_def_exp.cpp @@ -6,14 +6,14 @@ void test_simpl_dps(int x, int* res) { *res = x; } int test_one_branch(int x) { if (x < 0) { - return -x; + return (-x); } return x; } void test_one_branch_dps(int x, int* res) { if (x < 0) { - *res = -x; + *res = (-x); return; } *res = x; @@ -23,7 +23,7 @@ int test_branches(int x) { if (x > 0) { return x; } else { - return -x; + return (-x); } } @@ -31,7 +31,7 @@ void test_branches_dps(int x, int* res) { if (x > 0) { *res = x; } else { - *res = -x; + *res = (-x); } } diff --git a/tests/function/use_infix_ops/function_use_infix_ops_exp.cpp b/tests/function/use_infix_ops/function_use_infix_ops_exp.cpp index ac43852ec..f8b2152bc 100644 --- a/tests/function/use_infix_ops/function_use_infix_ops_exp.cpp +++ b/tests/function/use_infix_ops/function_use_infix_ops_exp.cpp @@ -16,13 +16,13 @@ void g() { x += 3; x -= 2; int y = 4; - x += -2 + y; + x += (-2) + y; x += y - 4; x += y - 4; x += y - 4; x -= y; x -= 4; - x += -4 - y; + x += (-4) - y; x *= 2; x *= 3 * y; x = y - x - 4; diff --git a/tests/gpu/thread_for_test.cpp b/tests/gpu/thread_for_test.cpp index b1c63ede8..ed813fe27 100644 --- a/tests/gpu/thread_for_test.cpp +++ b/tests/gpu/thread_for_test.cpp @@ -113,6 +113,56 @@ void sync_required(int *a, int N, int M) { __ghost(swap_groups, "items := fun i j -> &a[MINDEX2(N,M,j,i)] ~~>[GMem] 1+1"); } +__device; +void sync_required_write_after_read(int *a, int N, int M) { + __requires("A: int * int -> int"); + __requires("bpg: int, smem_sz: int"); + __reads("KernelParams(bpg, MSIZE2(N,M), smem_sz)"); + __preserves("ThreadsCtx(MINDEX1(0,0) ..+ MSIZE2(N,M))"); + __consumes("for i in 0..N -> for j in 0..M -> &a[MINDEX2(N,M,i,j)] ~~>[GMem] 0"); + __produces("for i in 0..N -> for j in 0..M -> &a[MINDEX2(N,M,i,j)] ~~>[GMem] 1 + 1"); + + __ghost(assume, "P := MSIZE2(N,M) = MSIZE2(M,N)", "msize_commute <- H"); + + __threadfor; for (int i = 0; i < N; i++) { + __xconsumes("for j in 0..M -> &a[MINDEX2(N,M,i,j)] ~~>[GMem] 0"); + __xproduces("desync_for j in ..M -> &a[MINDEX2(N,M,i,j)] ~~>[GMem] 0"); + + __threadfor; for (int j = 0; j < M; j++) { + __xconsumes("&a[MINDEX2(N,M,i,j)] ~~>[GMem] 0"); + __xproduces("&a[MINDEX2(N,M,i,j)] ~~>[GMem] 0"); + } + } + + __threadfor; for (int i = 0; i < N; i++) { + __xreads("desync_for j in ..M -> &a[MINDEX2(N,M,i,j)] ~~>[GMem] 0"); + + __threadfor; for (int j = 0; j < M; j++) { + __xreads("&a[MINDEX2(N,M,i,j)] ~~>[GMem] 0"); + __gmem_get(&a[MINDEX2(N,M,i,j)]); + } + } + + blocksync(); __with("H := desync_for i in ..N -> desync_for j in ..M -> &a[MINDEX2(N,M,i,j)] ~~>[GMem] 0"); + __ghost(swap_groups, "items := fun i j -> &a[MINDEX2(N,M,i,j)] ~~>[GMem] 0"); + __ghost(rewrite_threadsctx_sz, "by := msize_commute"); + + __threadfor; for (int i = 0; i < M; i++) { + __xconsumes("for j in 0..N -> &a[MINDEX2(N,M,j,i)] ~~>[GMem] 0"); + __xproduces("desync_for j in ..N -> &a[MINDEX2(N,M,j,i)] ~~>[GMem] 1+1"); + + __threadfor; for (int j = 0; j < N; j++) { + __xconsumes("&a[MINDEX2(N,M,j,i)] ~~>[GMem] 0"); + __xproduces("&a[MINDEX2(N,M,j,i)] ~~>[GMem] 1+1"); + __gmem_set(&a[MINDEX2(N,M,j,i)], 1 + 1); + } + } + + __ghost(rewrite_threadsctx_sz, "by := eq_sym(MSIZE2(N,M), MSIZE2(M,N), msize_commute)"); + blocksync(); __with("H := desync_for i in ..M -> desync_for j in ..N -> &a[MINDEX2(N,M,j,i)] ~~>[GMem] 1+1"); + __ghost(swap_groups, "items := fun i j -> &a[MINDEX2(N,M,j,i)] ~~>[GMem] 1+1"); +} + __device; void write_test1(int *a, int N) { __preserves("ThreadsCtx(MINDEX1(0,0) ..+ MSIZE1(N))"); @@ -142,13 +192,19 @@ __AXIOM(reduce_sum_add_right, "forall (n: int) (f: int -> int) (_: n >= 0) -> re __device; void read_thread_outer(int *a, int *b, int N) { - __requires("B: int -> int"); + __requires("B: int -> int, f: _Fraction"); __preserves("ThreadsCtx(MINDEX1(0,0) ..+ MSIZE1(N))"); __writes("desync_for i in ..N -> &a[i] ~~>[GMem] reduce_sum(N, B)"); - __reads("for i in 0..N -> &b[MINDEX1(N,i)] ~~>[GMem] B(i)"); + // NOTE: not a __reads because it shouldn't be possible to overwrite the content of b before the reads are done + // __consumes("_RO(f, for i in 0..N -> &b[MINDEX1(N,i)] ~~>[GMem] B(i))"); + // __ensures("g: _Fraction"); + // __produces("_RO(f - g, for i in 0..N -> &b[MINDEX1(N,i)] ~~>[GMem] B(i))"); + __preserves("_RO(f / range_count(0..N), desync_for t in ..N -> for i in 0..N -> &b[MINDEX1(N,i)]~~>[GMem] B(i))"); __threadfor; for (int t = 0; t < N; t++) { + __xreads("for i in 0..N -> &b[MINDEX1(N,i)] ~~>[GMem] B(i)"); __xwrites("&a[t] ~~>[GMem] reduce_sum(N, B)"); + __gmem_set(&a[t],0); __ghost(rewrite_linear, "inside := (fun v -> &a[t] ~~>[GMem] v), by := reduce_sum_empty(B)"); for (int i = 0; i < N; i++) { @@ -166,12 +222,14 @@ void read_thread_outer(int *a, int *b, int N) { __device; void read_thread_inner(int *a, int *b, int N) { - __requires("B: int -> int"); + __requires("B: int -> int, f: _Fraction"); __requires("bpg: int, smem_sz: int"); __reads("KernelParams(bpg, MSIZE1(N), smem_sz)"); __preserves("ThreadsCtx(MINDEX1(0,0) ..+ MSIZE1(N))"); __writes("desync_for i in ..N -> &a[MINDEX1(N,i)] ~~>[GMem] reduce_sum(N,B)"); - __reads("for i in 0..N -> &b[MINDEX1(N,i)] ~~>[GMem] B(i)"); + // NOTE: not a __reads because it shouldn't be possible to overwrite the content of b before the reads are done + // __reads("for i in 0..N -> &b[MINDEX1(N,i)] ~~>[GMem] B(i)"); + __preserves("_RO(f / range_count(0..N), desync_for t in ..N -> for i in 0..N -> &b[MINDEX1(N,i)] ~~>[GMem] B(i))"); __threadfor; for (int t = 0; t < N; t++) { __xwrites("&a[MINDEX1(N,t)] ~~>[GMem] reduce_sum(0, B)"); @@ -181,9 +239,12 @@ void read_thread_inner(int *a, int *b, int N) { for (int i = 0; i < N; i++) { __spreserves("desync_for t in ..N -> &a[MINDEX1(N,t)] ~~>[GMem] reduce_sum(i, B)"); + __threadfor; for (int t = 0; t < N; t++) { __xconsumes("&a[MINDEX1(N,t)] ~~>[GMem] reduce_sum(i, B)"); __xproduces("&a[MINDEX1(N,t)] ~~>[GMem] reduce_sum(i+1, B)"); + __xreads("for i in 0..N -> &b[MINDEX1(N,i)] ~~>[GMem] B(i)"); + __GHOST_BEGIN(focus, ro_matrix1_focus, "b, i"); const int va = __gmem_get(&a[MINDEX1(N,t)]); const int vb = __gmem_get(&b[MINDEX1(N,i)]); diff --git a/tests/gpu/thread_for_test.ml b/tests/gpu/thread_for_test.ml index 6a250e348..4eb9ff912 100644 --- a/tests/gpu/thread_for_test.ml +++ b/tests/gpu/thread_for_test.ml @@ -3,7 +3,7 @@ open Prelude open Target (* let _ = Flags.check_validity := false *) -let _ = Flags.typechecking_mode := Flags.Unverified +let _ = Flags.typechecking_mode := Flags.AnnotatedAndVerified let _ = Flags.pretty_matrix_notation := true let _ = Flags.recompute_resources_between_steps := false @@ -11,7 +11,8 @@ let _ = Run.script_cpp (fun _ -> !! Resources.ensure_computed (); (* Verify that removing sync causes typing error *) !! Trace.resource_error_expected (fun _ -> - Instr.delete [occFirst; cTopFunDef "sync_required"; cCall "blocksync"]; - Resources.ensure_computed ()); + Instr.delete [occFirst; cTopFunDef "sync_required"; cCall "blocksync"]); + !! Trace.resource_error_expected (fun _ -> + Instr.delete [occFirst; cTopFunDef "sync_required_write_after_read"; cCall "blocksync"]); !! Trace.generate_cuda ~check_expected:true (); ) diff --git a/tests/gpu/thread_for_test_exp.cpp b/tests/gpu/thread_for_test_exp.cpp index eee87a84a..5a1d32fa9 100644 --- a/tests/gpu/thread_for_test_exp.cpp +++ b/tests/gpu/thread_for_test_exp.cpp @@ -13,10 +13,12 @@ __device__ void basic(int* a, int N, int M) { __reads("KernelParams(bpg, MSIZE2(N, M), smem_sz)"); __threadfor; for (int i = 0; i < N; i++) { + __strict(); __xconsumes("for j in 0..M -> &a[i][j] ~~>[GMem] 0"); __xproduces("desync_for j in ..M -> &a[i][j] ~~>[GMem] 1"); __threadfor; for (int j = 0; j < M; j++) { + __strict(); __xconsumes("&a[i][j] ~~>[GMem] 0"); __xproduces("&a[i][j] ~~>[GMem] 1"); __gmem_set(&a[i][j], 1); @@ -45,10 +47,12 @@ __device__ void retile_desyncgroups(int* a, int N, int M) { __ghost(assume, "P := (M >= 0)"); __threadfor; for (int i = 0; i < N; i++) { + __strict(); __xconsumes("for j in 0..M -> &a[i * M + j] ~~>[GMem] 0"); __xproduces("desync_for j in ..M -> &a[i * M + j] ~~>[GMem] 1"); __threadfor; for (int j = 0; j < M; j++) { + __strict(); __xconsumes("&a[i * M + j] ~~>[GMem] 0"); __xproduces("&a[i * M + j] ~~>[GMem] 1"); __gmem_set(&a[i * M + j], 1); @@ -61,10 +65,12 @@ __device__ void retile_desyncgroups(int* a, int N, int M) { __ghost(rewrite_threadsctx_sz, "by := eq_retile_3"); __threadfor; for (int i = 0; i < N * M / 32; i++) { + __strict(); __xconsumes("desync_for j in ..32 -> &a[i * 32 + j] ~~>[GMem] 1"); __xproduces("desync_for j in ..32 -> &a[i * 32 + j] ~~>[GMem] 1 + 1"); __threadfor; for (int j = 0; j < 32; j++) { + __strict(); __xconsumes("&a[i * 32 + j] ~~>[GMem] 1"); __xproduces("&a[i * 32 + j] ~~>[GMem] 1 + 1"); const int va = __gmem_get(&a[i * 32 + j]); @@ -94,10 +100,12 @@ __device__ void sync_required(int* a, int N, int M) { __ghost(assume, "P := (MSIZE2(N, M) = MSIZE2(M, N))", "msize_commute <- H"); __threadfor; for (int i = 0; i < N; i++) { + __strict(); __xconsumes("for j in 0..M -> &a[i][j] ~~>[GMem] 0"); __xproduces("desync_for j in ..M -> &a[i][j] ~~>[GMem] 1"); __threadfor; for (int j = 0; j < M; j++) { + __strict(); __xconsumes("&a[i][j] ~~>[GMem] 0"); __xproduces("&a[i][j] ~~>[GMem] 1"); __gmem_set(&a[i][j], 1); @@ -111,10 +119,12 @@ __device__ void sync_required(int* a, int N, int M) { __ghost(rewrite_threadsctx_sz, "by := msize_commute"); __threadfor; for (int i = 0; i < M; i++) { + __strict(); __xconsumes("for j in 0..N -> &a[j][i] ~~>[GMem] 1"); __xproduces("desync_for j in ..N -> &a[j][i] ~~>[GMem] 1 + 1"); __threadfor; for (int j = 0; j < N; j++) { + __strict(); __xconsumes("&a[j][i] ~~>[GMem] 1"); __xproduces("&a[j][i] ~~>[GMem] 1 + 1"); __gmem_set(&a[j][i], __gmem_get(&a[j][i]) + 1); @@ -129,11 +139,71 @@ __device__ void sync_required(int* a, int N, int M) { __ghost(swap_groups, "items := fun i j -> &a[j][i] ~~>[GMem] 1 + 1"); } +__device__ void sync_required_write_after_read(int* a, int N, int M) { + __requires("A: int * int -> int"); + __requires("bpg: int"); + __requires("smem_sz: int"); + __consumes("for i in 0..N -> for j in 0..M -> &a[i][j] ~~>[GMem] 0"); + __produces("for i in 0..N -> for j in 0..M -> &a[i][j] ~~>[GMem] 1 + 1"); + __preserves("ThreadsCtx(MINDEX1(0, 0)..+MSIZE2(N, M))"); + __reads("KernelParams(bpg, MSIZE2(N, M), smem_sz)"); + __ghost(assume, "P := (MSIZE2(N, M) = MSIZE2(M, N))", "msize_commute <- H"); + __threadfor; + for (int i = 0; i < N; i++) { + __strict(); + __xconsumes("for j in 0..M -> &a[i][j] ~~>[GMem] 0"); + __xproduces("desync_for j in ..M -> &a[i][j] ~~>[GMem] 0"); + __threadfor; + for (int j = 0; j < M; j++) { + __strict(); + __xpreserves("&a[i][j] ~~>[GMem] 0"); + } + } + __threadfor; + for (int i = 0; i < N; i++) { + __strict(); + __xreads("desync_for j in ..M -> &a[i][j] ~~>[GMem] 0"); + __threadfor; + for (int j = 0; j < M; j++) { + __strict(); + __xreads("&a[i][j] ~~>[GMem] 0"); + __gmem_get(&a[i][j]); + } + } + blocksync(); + __with( + "H := desync_for i in ..N -> desync_for j in ..M -> &a[i][j] ~~>[GMem] " + "0"); + __ghost(swap_groups, "items := fun i j -> &a[i][j] ~~>[GMem] 0"); + __ghost(rewrite_threadsctx_sz, "by := msize_commute"); + __threadfor; + for (int i = 0; i < M; i++) { + __strict(); + __xconsumes("for j in 0..N -> &a[j][i] ~~>[GMem] 0"); + __xproduces("desync_for j in ..N -> &a[j][i] ~~>[GMem] 1 + 1"); + __threadfor; + for (int j = 0; j < N; j++) { + __strict(); + __xconsumes("&a[j][i] ~~>[GMem] 0"); + __xproduces("&a[j][i] ~~>[GMem] 1 + 1"); + __gmem_set(&a[j][i], 1 + 1); + } + } + __ghost(rewrite_threadsctx_sz, + "by := eq_sym(MSIZE2(N, M), MSIZE2(M, N), msize_commute)"); + blocksync(); + __with( + "H := desync_for i in ..M -> desync_for j in ..N -> &a[j][i] ~~>[GMem] 1 " + "+ 1"); + __ghost(swap_groups, "items := fun i j -> &a[j][i] ~~>[GMem] 1 + 1"); +} + __device__ void write_test1(int* a, int N) { __preserves("ThreadsCtx(MINDEX1(0, 0)..+MSIZE1(N))"); __writes("desync_for i in ..N -> &a[i] ~~>[GMem] 1"); __threadfor; for (int i = 0; i < N; i++) { + __strict(); __xwrites("&a[i] ~~>[GMem] 1"); __gmem_set(&a[i], 1); } @@ -165,17 +235,25 @@ __ghost(assert_prop, __device__ void read_thread_outer(int* a, int* b, int N) { __requires("B: int -> int"); + __requires("f: _Fraction"); __preserves("ThreadsCtx(MINDEX1(0, 0)..+MSIZE1(N))"); + __preserves( + "_RO(f / range_count(0..N), desync_for t in ..N -> b ~> Matrix1Of(N, " + "GMem, B))"); __writes("desync_for i in ..N -> &a[i] ~~>[GMem] reduce_sum(N, B)"); - __reads("b ~> Matrix1Of(N, GMem, B)"); __threadfor; for (int t = 0; t < N; t++) { + __strict(); __xwrites("&a[t] ~~>[GMem] reduce_sum(N, B)"); + __xreads("b ~> Matrix1Of(N, GMem, B)"); __gmem_set(&a[t], 0); __ghost(rewrite_linear, "inside := fun v -> &a[t] ~~>[GMem] v, by := reduce_sum_empty(B)"); for (int i = 0; i < N; i++) { + __strict(); + __spreserves("ThreadsCtx(MINDEX2(N, 0, t, 0)..+MSIZE0())"); __spreserves("&a[t] ~~>[GMem] reduce_sum(i, B)"); + __sreads("b ~> Matrix1Of(N, GMem, B)"); const __ghost_fn focus = __ghost_begin(ro_matrix1_focus, "matrix := b, i := i"); const int va = __gmem_get(&a[t]); @@ -192,25 +270,34 @@ __device__ void read_thread_outer(int* a, int* b, int N) { __device__ void read_thread_inner(int* a, int* b, int N) { __requires("B: int -> int"); + __requires("f: _Fraction"); __requires("bpg: int"); __requires("smem_sz: int"); __preserves("ThreadsCtx(MINDEX1(0, 0)..+MSIZE1(N))"); + __preserves( + "_RO(f / range_count(0..N), desync_for t in ..N -> b ~> Matrix1Of(N, " + "GMem, B))"); __writes("desync_for i in ..N -> &a[i] ~~>[GMem] reduce_sum(N, B)"); __reads("KernelParams(bpg, MSIZE1(N), smem_sz)"); - __reads("b ~> Matrix1Of(N, GMem, B)"); __threadfor; for (int t = 0; t < N; t++) { + __strict(); __xwrites("&a[t] ~~>[GMem] reduce_sum(0, B)"); __gmem_set(&a[t], 0); __ghost(rewrite_linear, "inside := fun v -> &a[t] ~~>[GMem] v, by := reduce_sum_empty(B)"); } for (int i = 0; i < N; i++) { + __strict(); + __spreserves("ThreadsCtx(MINDEX1(0, 0)..+MSIZE1(N))"); __spreserves("desync_for t in ..N -> &a[t] ~~>[GMem] reduce_sum(i, B)"); + __sreads("desync_for t in ..N -> b ~> Matrix1Of(N, GMem, B)"); __threadfor; for (int t = 0; t < N; t++) { + __strict(); __xconsumes("&a[t] ~~>[GMem] reduce_sum(i, B)"); __xproduces("&a[t] ~~>[GMem] reduce_sum(i + 1, B)"); + __xreads("b ~> Matrix1Of(N, GMem, B)"); const __ghost_fn focus = __ghost_begin(ro_matrix1_focus, "matrix := b, i := i"); const int va = __gmem_get(&a[t]); diff --git a/tests/gpu/thread_for_test_exp.cu b/tests/gpu/thread_for_test_exp.cu index a8517eb5b..09a1c4aa4 100644 --- a/tests/gpu/thread_for_test_exp.cu +++ b/tests/gpu/thread_for_test_exp.cu @@ -1,12 +1,7 @@ #include - - - - - - __device__ void basic (int __ctx_sz, int __tid, int* a, int N, int M) { +__device__ void basic(int __ctx_sz, int __tid, int* a, int N, int M) { const int __ctx_sz_0 = __ctx_sz / N; const int __i0 = __tid % __ctx_sz / __ctx_sz_0; const int __ctx_sz_1 = __ctx_sz_0 / M; @@ -15,8 +10,8 @@ __syncthreads(); } - __device__ void retile_desyncgroups (int __ctx_sz, int __tid, int* a, int N, int M -) { +__device__ void retile_desyncgroups(int __ctx_sz, int __tid, int* a, int N, + int M) { const int __ctx_sz_0 = __ctx_sz / N; const int __i0 = __tid % __ctx_sz / __ctx_sz_0; const int __ctx_sz_1 = __ctx_sz_0 / M; @@ -31,8 +26,7 @@ __syncthreads(); } - __device__ void sync_required (int __ctx_sz, int __tid, int* a, int N, int M -) { +__device__ void sync_required(int __ctx_sz, int __tid, int* a, int N, int M) { const int __ctx_sz_0 = __ctx_sz / N; const int __i0 = __tid % __ctx_sz / __ctx_sz_0; const int __ctx_sz_1 = __ctx_sz_0 / M; @@ -47,41 +41,59 @@ __syncthreads(); } - __device__ void write_test1 (int __ctx_sz, int __tid, int* a, int N) { +__device__ void sync_required_write_after_read(int __ctx_sz, int __tid, int* a, + int N, int M) { + const int __ctx_sz_0 = __ctx_sz / N; + const int __i0 = __tid % __ctx_sz / __ctx_sz_0; + const int __ctx_sz_1 = __ctx_sz_0 / M; + const int __j1 = __tid % __ctx_sz_0 / __ctx_sz_1; + const int __ctx_sz_2 = __ctx_sz / N; + const int __i2 = __tid % __ctx_sz / __ctx_sz_2; + const int __ctx_sz_3 = __ctx_sz_2 / M; + const int __j3 = __tid % __ctx_sz_2 / __ctx_sz_3; + const int __ctx_sz_4 = __ctx_sz / M; + const int __i4 = __tid % __ctx_sz / __ctx_sz_4; + const int __ctx_sz_5 = __ctx_sz_4 / N; + const int __j5 = __tid % __ctx_sz_4 / __ctx_sz_5; + a[MINDEX2(N, M, __i2, __j3)]; + __syncthreads(); + a[MINDEX2(N, M, __j5, __i4)] = 1 + 1; + __syncthreads(); +} + +__device__ void write_test1(int __ctx_sz, int __tid, int* a, int N) { const int __ctx_sz_0 = __ctx_sz / N; const int __i0 = __tid % __ctx_sz / __ctx_sz_0; a[__i0] = 1; } - __device__ void write_test2 (int __ctx_sz, int __tid, int* a, int N) { +__device__ void write_test2(int __ctx_sz, int __tid, int* a, int N) { write_test1(__ctx_sz, __tid, a, N); __syncthreads(); } - __device__ void read_thread_outer (int __ctx_sz, int __tid, int* a, int* b, int N -) { +__device__ void read_thread_outer(int __ctx_sz, int __tid, int* a, int* b, + int N) { const int __ctx_sz_0 = __ctx_sz / N; const int __t0 = __tid % __ctx_sz / __ctx_sz_0; a[__t0] = 0; - for (int i = 0; i < N; i++) { + for (int i = 0; i < N; i++) { const int va = a[__t0]; const int vb = b[MINDEX1(N, i)]; a[__t0] = va + vb; } } - __device__ void read_thread_inner (int __ctx_sz, int __tid, int* a, int* b, int N -) { +__device__ void read_thread_inner(int __ctx_sz, int __tid, int* a, int* b, + int N) { const int __ctx_sz_0 = __ctx_sz / N; const int __t0 = __tid % __ctx_sz / __ctx_sz_0; const int __ctx_sz_1 = __ctx_sz / N; const int __t1 = __tid % __ctx_sz / __ctx_sz_1; a[MINDEX1(N, __t0)] = 0; - for (int i = 0; i < N; i++) { + for (int i = 0; i < N; i++) { const int va = a[MINDEX1(N, __t1)]; const int vb = b[MINDEX1(N, i)]; a[MINDEX1(N, __t1)] = va + vb; } } - - diff --git a/tests/loop/extend_range/loop_extend_range_exp.cpp b/tests/loop/extend_range/loop_extend_range_exp.cpp index 1295fea69..aa73d9641 100644 --- a/tests/loop/extend_range/loop_extend_range_exp.cpp +++ b/tests/loop/extend_range/loop_extend_range_exp.cpp @@ -14,7 +14,7 @@ int main() { } int ld = 2; int u = N + 5; - for (int k = -ld; k < u; k++) { + for (int k = (-ld); k < u; k++) { if (0 <= k && k < N) { x += k; } diff --git a/tests/loop/shift_range/loop_shift_range_basic_doc_exp.cpp b/tests/loop/shift_range/loop_shift_range_basic_doc_exp.cpp index afec15f5d..658f35c71 100644 --- a/tests/loop/shift_range/loop_shift_range_basic_doc_exp.cpp +++ b/tests/loop/shift_range/loop_shift_range_basic_doc_exp.cpp @@ -3,7 +3,7 @@ int main() { int x = 0; for (int i2 = 0; i2 < 12 - 2; i2++) { - const int i = i2 - -2; + const int i = i2 - (-2); __ghost(assume, "P := in_range(i, 2..12)"); x += i; } diff --git a/tests/loop/tile/loop_tile.ml b/tests/loop/tile/loop_tile.ml index 683dc5113..6d0e0a0ce 100644 --- a/tests/loop/tile/loop_tile.ml +++ b/tests/loop/tile/loop_tile.ml @@ -2,14 +2,6 @@ open Optitrust open Prelude let _ = Run.script_cpp (fun _ -> - - !! Loop_basic.tile (trm_int 2) ~index:"b${id}" ~bound:TileDivides [cFunDef "f"; cFor "x"]; - !! Loop_basic.tile (trm_int 2) ~bound:TileBoundMin [cFunDef "f"; cFor "y"]; - !! Loop_basic.tile (trm_int 2) ~bound:TileBoundAnd [cFunDef "f"; cFor "z"]; - !! Loop_basic.tile (trm_int 2) ~index:"b${id}" ~bound:TileDivides [cFunDef "f"; cFor "i"]; - !! Loop_basic.tile (trm_int 2) ~bound:TileBoundMin [cFunDef "f"; cFor "j"]; - !! Loop_basic.tile (trm_int 2) ~bound:TileBoundAnd [cFunDef "f"; cFor "k"]; - !! Resources.ensure_computed (); !! Loop_basic.tile (trm_int 4) ~bound:TileDivides [cFunDef "matrix_copy"; cFor "i"]; (* FIXME: @@ -17,4 +9,12 @@ let _ = Run.script_cpp (fun _ -> *) !! Resources.ensure_computed (); + Flags.typechecking_mode := Unverified; + + !! Loop_basic.tile (trm_int 2) ~index:"b${id}" ~bound:TileDivides [cFunDef "f"; cFor "x"]; + !! Loop_basic.tile (trm_int 2) ~bound:TileBoundMin [cFunDef "f"; cFor "y"]; + !! Loop_basic.tile (trm_int 2) ~bound:TileBoundAnd [cFunDef "f"; cFor "z"]; + !! Loop_basic.tile (trm_int 2) ~index:"b${id}" ~bound:TileDivides [cFunDef "f"; cFor "i"]; + !! Loop_basic.tile (trm_int 2) ~bound:TileBoundMin [cFunDef "f"; cFor "j"]; + !! Loop_basic.tile (trm_int 2) ~bound:TileBoundAnd [cFunDef "f"; cFor "k"]; ) diff --git a/tests/loop/tile/loop_tile_doc.ml b/tests/loop/tile/loop_tile_doc.ml index bc3161fdb..001a169e8 100644 --- a/tests/loop/tile/loop_tile_doc.ml +++ b/tests/loop/tile/loop_tile_doc.ml @@ -1,6 +1,8 @@ open Optitrust open Prelude +let _ = Flags.typechecking_mode := Unverified + let _ = Run.script_cpp (fun _ -> !! Loop_basic.tile (lit "3") ~index:"bi" ~bound:TileDivides [cFor "i"]; diff --git a/tests/loop/unroll/loop_unroll.ml b/tests/loop/unroll/loop_unroll.ml index f4ef10f4e..22403d9d2 100644 --- a/tests/loop/unroll/loop_unroll.ml +++ b/tests/loop/unroll/loop_unroll.ml @@ -3,11 +3,12 @@ open Target let _ = Run.script_cpp (fun _ -> + !! Loop.unroll [nbMulti; cFunBody "iter_contract_ro"; cFor "x"]; + + Flags.typechecking_mode := Unverified; + !! Loop.unroll [cFor "i"]; !! Loop.unroll [cFor "j"]; !! Loop.unroll ~nest_of:2 [cFor "k"]; - - !! Loop.unroll [nbMulti; cFunBody "iter_contract_ro"; cFor "x"]; - ) diff --git a/tests/loop/unroll/loop_unroll_basic_doc.ml b/tests/loop/unroll/loop_unroll_basic_doc.ml index e09195b02..2f3c9eaf9 100644 --- a/tests/loop/unroll/loop_unroll_basic_doc.ml +++ b/tests/loop/unroll/loop_unroll_basic_doc.ml @@ -2,7 +2,7 @@ open Optitrust open Target -(* let _ = Flags.check_validity := true *) +let _ = Flags.typechecking_mode := Unverified let _ = Run.script_cpp (fun _ -> diff --git a/tests/loop/unroll/loop_unroll_doc.ml b/tests/loop/unroll/loop_unroll_doc.ml index 7b9388eeb..3af78da8e 100644 --- a/tests/loop/unroll/loop_unroll_doc.ml +++ b/tests/loop/unroll/loop_unroll_doc.ml @@ -1,6 +1,8 @@ open Optitrust open Target +let _ = Flags.typechecking_mode := Unverified + let _ = Run.script_cpp (fun _ -> !! Loop.unroll [cFor "a"]; diff --git a/tests/loop/unroll/loop_unroll_exp.cpp b/tests/loop/unroll/loop_unroll_exp.cpp index 976f73f34..53761ada8 100644 --- a/tests/loop/unroll/loop_unroll_exp.cpp +++ b/tests/loop/unroll/loop_unroll_exp.cpp @@ -13,17 +13,17 @@ void f() { int c = 3; int d = c + 4; int e = d + 5; - int a1 = 1; - int b2 = a1 + 2; - int c3 = 3; - int d4 = c3 + 4; - int e5 = d4 + 5; + int a3 = 1; + int b4 = a3 + 2; + int c5 = 3; + int d6 = c5 + 4; + int e7 = d6 + 5; int x = 4; int y = 5; - int x6 = 5; - int y7 = 6; - int x8 = 6; - int y9 = 7; + int x8 = 5; + int y9 = 6; + int x10 = 6; + int y11 = 7; s = 0; s = 1; s = 1; @@ -41,14 +41,14 @@ void iter_contract_ro(int* M) { "i := 0, items := fun (x: int) -> &M[MINDEX1(3, x)] ~> Cell"); acc += M[MINDEX1(3, 0)]; __ghost_end(__ghost_pair_1); - const __ghost_fn __ghost_pair_110 = __ghost_begin( + const __ghost_fn __ghost_pair_11 = __ghost_begin( ro_group_focus, "i := 1, items := fun (x: int) -> &M[MINDEX1(3, x)] ~> Cell"); acc += M[MINDEX1(3, 1)]; - __ghost_end(__ghost_pair_110); - const __ghost_fn __ghost_pair_111 = __ghost_begin( + __ghost_end(__ghost_pair_11); + const __ghost_fn __ghost_pair_12 = __ghost_begin( ro_group_focus, "i := 2, items := fun (x: int) -> &M[MINDEX1(3, x)] ~> Cell"); acc += M[MINDEX1(3, 2)]; - __ghost_end(__ghost_pair_111); + __ghost_end(__ghost_pair_12); } diff --git a/tests/resources/contracts/loop_mode_check.ml b/tests/resources/contracts/loop_mode_check.ml index 061b0907d..240ca5765 100644 --- a/tests/resources/contracts/loop_mode_check.ml +++ b/tests/resources/contracts/loop_mode_check.ml @@ -2,7 +2,7 @@ open Optitrust open Prelude (* let _ = Flags.check_validity := false *) -let _ = Flags.typechecking_mode := Flags.Unverified +let _ = Flags.typechecking_mode := Flags.AnnotatedAndVerified let _ = Flags.recompute_resources_between_steps := false let _ = Run.script_cpp (fun () -> diff --git a/tests/sequence/elim_instr/sequence_elim_instr.ml b/tests/sequence/elim_instr/sequence_elim_instr.ml index 5e6bf95aa..0513bc260 100644 --- a/tests/sequence/elim_instr/sequence_elim_instr.ml +++ b/tests/sequence/elim_instr/sequence_elim_instr.ml @@ -2,7 +2,7 @@ open Optitrust open Target -(* let _ = Flags.check_validity := true *) +let _ = Flags.typechecking_mode := Unverified let _ = Run.script_cpp ( fun _ -> diff --git a/tests/variable/local_name/variable_local_name.ml b/tests/variable/local_name/variable_local_name.ml index 1d4c6bd4b..6d2cb8ae4 100644 --- a/tests/variable/local_name/variable_local_name.ml +++ b/tests/variable/local_name/variable_local_name.ml @@ -26,5 +26,7 @@ let _ = Run.script_cpp (fun _ -> !! Variable.local_name ~var:"a" ~local_var:"x" [cFunBody "ok3"; tSpanSeq [cForBody "i"]]; - !! Variable.local_name ~var:"a" ~local_var:"x" [cFunBody "ok4"; tSpan [tBefore; cVarDef "b"] [tAfter; sInstr "a++"]]; + (* !! Show.At.trm ~style:(Style.internal_ast_only_desc ()) [cFunBody "ok4"]; + !! Marks.add "end" [nbMulti; tAfter; cFunBody "ok4"; cCall ~args:[[cPrimCall ~args:[[cVar "a"]] (Prim_unop Unop_post_incr)]] "__ignore"]; *) + !! Variable.local_name ~var:"a" ~local_var:"x" [cFunBody "ok4"; tSpan [tBefore; cVarDef "b"] [tAfter; cInstr [cPrimCall ~args:[[cVar "a"]] (Prim_unop Unop_post_incr)]]]; ) diff --git a/tests/variable/local_name/variable_local_name_exp.cpp b/tests/variable/local_name/variable_local_name_exp.cpp index ed30dff4c..b9ae5e24e 100644 --- a/tests/variable/local_name/variable_local_name_exp.cpp +++ b/tests/variable/local_name/variable_local_name_exp.cpp @@ -59,9 +59,9 @@ void ko_scope() { __pure(); int x = 0; int a = 0; - int x4 = a; -l: { x4++; } - a = x4; + int x2 = a; +l: { x2++; } + a = x2; } void ok3() { diff --git a/tests/variable/rename/variable_rename_exp.cpp b/tests/variable/rename/variable_rename_exp.cpp index 61ffa6c02..1563f2e91 100644 --- a/tests/variable/rename/variable_rename_exp.cpp +++ b/tests/variable/rename/variable_rename_exp.cpp @@ -5,7 +5,7 @@ int f(int x) { } int g(int x) { - int y = -1; + int y = (-1); return y + x; } diff --git a/tests/variable/renames/variable_renames_exp.cpp b/tests/variable/renames/variable_renames_exp.cpp index 002101f42..9686d7808 100644 --- a/tests/variable/renames/variable_renames_exp.cpp +++ b/tests/variable/renames/variable_renames_exp.cpp @@ -5,7 +5,7 @@ int f(int x) { } int g(int x) { - int y = -1; + int y = (-1); return y + x; } From bda060cbcd1828d74da8d954bf59dcd72e6a9125 Mon Sep 17 00:00:00 2001 From: Thomas Koehler Date: Fri, 31 Jul 2026 14:35:40 +0200 Subject: [PATCH 23/23] better hole and desync coercion through RO --- lib/ast/trm_unify.ml | 6 ++++-- .../resources/resource_computation.ml | 19 +++++++++++++------ lib/framework/resources/resource_formula.ml | 1 + lib/transfo/loop_basic.ml | 2 +- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/lib/ast/trm_unify.ml b/lib/ast/trm_unify.ml index 0d54b68c5..463b06b18 100644 --- a/lib/ast/trm_unify.ml +++ b/lib/ast/trm_unify.ml @@ -55,6 +55,8 @@ let rec unfold_if_resolved_evar (t : trm) (evar_ctx : 'a unification_ctx) : | None -> (trm_apps fn args, evar_ctx)) | _ -> (t, evar_ctx) +let hole_var = toplevel_var "hole" + (** [normalize_trm t evar_ctx]: tries to normalize [t], aiming to match equivalent trms with different syntax Performs the following normalisations: - normalize mindex : @@ -156,9 +158,9 @@ and trm_unify (t_left : trm) (t_right : trm) let res = match (t_left.desc, t_right.desc) with (* -- FIXME: hole hack *) - | _, Trm_var h when String.starts_with ~prefix:"__hole" h.name -> + | _, Trm_apps (h, [t], [], []) when trm_is_var ~var:hole_var h -> Some evar_ctx - | Trm_var h, _ when String.starts_with ~prefix:"__hole" h.name -> + | Trm_apps (h, [t], [], []), _ when trm_is_var ~var:hole_var h -> Some evar_ctx (* -- *) | Trm_var x_left, Trm_var x_right when var_eq x_left x_right -> diff --git a/lib/framework/resources/resource_computation.ml b/lib/framework/resources/resource_computation.ml index 99f232cde..eaf295fea 100644 --- a/lib/framework/resources/resource_computation.ml +++ b/lib/framework/resources/resource_computation.ml @@ -201,10 +201,6 @@ let missing_types_in_contracts = ref false let rec compute_pure_typ (env: pure_env) ?(typ_hint: typ option) (t: trm): typ = let typ = match t.desc with | Trm_var v -> - if String.starts_with ~prefix:"__hole" v.name then - (* FIXME: hole hack *) - unsome_or_trm_fail t "unknown hole type" t.typ - else begin match Resource_set.find_pure v (Resource_set.make ~pure:env.res ()) with | Some typ -> typ | None -> failwith "Variable '%s' could not be found in environment" (var_to_string v) @@ -291,6 +287,8 @@ let rec compute_pure_typ (env: pure_env) ?(typ_hint: typ option) (t: trm): typ = if gargs <> [] then failwith "Pure functions do not have ghost arguments"; if gbind <> [] then failwith "Pure functions do not have ghost output bindings"; begin match f.desc, args with + (* | Trm_var h, [t] when var_eq h Trm_unify.hole_var -> + t *) | Trm_prim (_, Prim_binop Binop_array_access), [arr; index] -> let arr_typ = compute_pure_typ env arr in let index_typ = compute_pure_typ env index in @@ -481,6 +479,10 @@ let subtract_linear_resource_item ~(split_frac: bool) ((x, formula): resource_it (fun inner_formula idx range inner_formula_candidate () -> formula_group idx range (may_coerce_desyncgroup inner_formula_candidate inner_formula) ); + Pattern.((formula_read_only __ !__) ^* (formula_read_only !__ !__)) + (fun inner_formula frac inner_formula_candidate () -> + formula_read_only ~frac (may_coerce_desyncgroup inner_formula_candidate inner_formula) + ); Pattern.__ (fun () -> formula_candidate) ] in @@ -541,6 +543,7 @@ let subtract_linear_resource_item ~(split_frac: bool) ((x, formula): resource_it function faster on most frequent cases *) extract (fun (h, formula_candidate) -> let { frac = cur_frac; formula = formula_candidate } = formula_read_only_inv_all formula_candidate in + let formula_candidate = may_coerce_desyncgroup formula_candidate formula in let* evar_ctx = trm_unify formula formula_candidate evar_ctx (try_compute_and_unify_typ pure_ctx) in Some ( { hyp ; inst_by = Formula_inst.inst_split_read_only ~new_frac ~old_frac:cur_frac h; used_formula = formula_read_only ~frac:(trm_var new_frac) formula_candidate }, @@ -1268,18 +1271,21 @@ let sync_simplification ?(magic = false) (res: resource_set): resource_set = formula_If cond (simplify mem_fn h)); Pattern.(formula_desyncgroup !__ !__ !__) (fun idx bound sub () -> formula_group idx (formula_range (trm_int 0) bound (trm_int 1)) (simplify mem_fn sub)); + Pattern.(formula_read_only !__ !__) (fun frac inner () -> + formula_read_only ~frac (simplify mem_fn inner) + ); Pattern.(formula_points_to !__ !__ !__) (fun var model mem_typ () -> if magic then t else match (find_mem_fn_proof mem_fn mem_typ) with | Some _ -> t | None -> formula_sync mem_fn t - ); + ); Pattern.(formula_uninit_cell !__ !__) (fun var mem_typ () -> if magic then t else match (find_mem_fn_proof mem_fn mem_typ) with | Some _ -> t | None -> formula_sync mem_fn t - ); + ); Pattern.__ (fun () -> if magic then t else formula_sync mem_fn t) ] in @@ -2216,6 +2222,7 @@ let init_ctx = Resource_set.make ~pure:[ Resource_formula.var_spec_override_ret_implicit, (let typ = new_var "T" in typ_pure_fun [typ, typ_type] (typ_prop)); Resource_trm.var_ghost_ret, typ_type; Resource_trm.var_ghost_fn, typ_type; (* Maybe add an alias to trm_fun [] trm_ghost_ret *) + Trm_unify.hole_var, (let typ = new_var "T" in typ_pure_fun [typ, typ_type] (typ_var typ)); Resource_trm.var_arbitrary, (let typ = new_var "T" in typ_pure_fun [typ, typ_type] (typ_var typ)); Resource_trm.var_admit, (let prop = new_var "P" in typ_pure_fun [prop, typ_prop] (typ_var prop)); Resource_trm.var_admitted, typ_auto; diff --git a/lib/framework/resources/resource_formula.ml b/lib/framework/resources/resource_formula.ml index ebfff6cf2..d20d8ef1b 100644 --- a/lib/framework/resources/resource_formula.ml +++ b/lib/framework/resources/resource_formula.ml @@ -616,6 +616,7 @@ let rec formula_has_desyncgroups (f: formula): bool = Pattern.pattern_match f [ Pattern.(formula_desyncgroup __ __ __) (fun () -> true); Pattern.(formula_group __ __ !__) (fun body () -> formula_has_desyncgroups body); + Pattern.(formula_read_only __ !__) (fun inner () -> formula_has_desyncgroups inner); Pattern.(__) (fun () -> false) ] diff --git a/lib/transfo/loop_basic.ml b/lib/transfo/loop_basic.ml index ffdf282b0..06b4154ae 100644 --- a/lib/transfo/loop_basic.ml +++ b/lib/transfo/loop_basic.ml @@ -421,6 +421,7 @@ let fission_on (mark_loops : mark) (mark_between_loops : mark) (index : int) (t writes in first loop after index i. *) let%transfo fission_basic ?(mark_loops : mark = no_mark) ?(mark_between_loops : mark = no_mark) (tg : target) : unit = (* TODO: figure out best nobrace/iter/resource interleaving *) + if Flags.annotated_and_verified () then Resources.ensure_computed (); Nobrace_transfo.remove_after (fun _ -> Target.iter (fun p_before -> let (p_seq, split_i) = Path.extract_last_dir_before p_before in @@ -428,7 +429,6 @@ let%transfo fission_basic ?(mark_loops : mark = no_mark) ?(mark_between_loops : (* DEBUG: let debug_p = Path.parent p_loop in Show.res ~msg:"res1" ~ast:(get_trm_at_exn (target_of_path debug_p)) ); *) - if Flags.annotated_and_verified () then Resources.ensure_computed (); apply_at_path (fission_on mark_loops mark_between_loops split_i) p_loop; ) tg );