fpy2 0.2.3__tar.gz → 0.2.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fpy2-0.2.4/PKG-INFO +190 -0
- fpy2-0.2.4/README.md +159 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/__init__.py +1 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/analysis/__init__.py +5 -1
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/analysis/alias.py +29 -3
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/analysis/array_size.py +251 -73
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/analysis/context_use.py +84 -10
- fpy2-0.2.4/fpy2/analysis/digit_bound/__init__.py +34 -0
- fpy2-0.2.4/fpy2/analysis/digit_bound/infer.py +1778 -0
- fpy2-0.2.4/fpy2/analysis/digit_bound/solver.py +419 -0
- fpy2-0.2.4/fpy2/analysis/digit_bound/store.py +265 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/analysis/format_infer/__init__.py +4 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/analysis/format_infer/analysis.py +657 -166
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/analysis/format_infer/format.py +22 -8
- fpy2-0.2.4/fpy2/analysis/hoistability.py +228 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/analysis/partial_eval.py +7 -7
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/analysis/reaching_defs.py +15 -1
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/analysis/storage_infer.py +103 -17
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/analysis/type_infer.py +4 -4
- fpy2-0.2.4/fpy2/analysis/value_class.py +1975 -0
- fpy2-0.2.4/fpy2/ast/accessors.py +149 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/ast/fpyast.py +16 -6
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/backend/__init__.py +3 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/backend/cpp/compiler.py +187 -73
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/backend/cpp/emitter.py +769 -259
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/backend/cpp/storage.py +23 -6
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/backend/cpp/target.py +58 -30
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/backend/cpp/types.py +16 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/backend/cpp/unbox.py +8 -1
- fpy2-0.2.4/fpy2/backend/cpp/unfold_round.py +72 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/backend/cpp/utils.py +4 -1
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/backend/fpc.py +2 -2
- fpy2-0.2.4/fpy2/backend/triton/__init__.py +47 -0
- fpy2-0.2.4/fpy2/backend/triton/compiler.py +167 -0
- fpy2-0.2.4/fpy2/backend/triton/emitter.py +2895 -0
- fpy2-0.2.4/fpy2/backend/triton/launcher.py +265 -0
- fpy2-0.2.4/fpy2/backend/triton/normalize.py +131 -0
- fpy2-0.2.4/fpy2/backend/triton/split_names.py +84 -0
- fpy2-0.2.4/fpy2/backend/triton/storage.py +196 -0
- fpy2-0.2.4/fpy2/backend/triton/target.py +258 -0
- fpy2-0.2.4/fpy2/backend/triton/types.py +92 -0
- fpy2-0.2.4/fpy2/backend/triton/unfold_round.py +109 -0
- fpy2-0.2.4/fpy2/backend/triton/vectorize.py +471 -0
- fpy2-0.2.4/fpy2/backend/unfold_round.py +308 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/decorator.py +26 -3
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/interpret/byte.py +37 -2
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/ops.py +11 -19
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/__init__.py +26 -0
- fpy2-0.2.4/fpy2/strategies/assert_elim.py +55 -0
- fpy2-0.2.4/fpy2/strategies/exit_single.py +78 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/fixed_rescale.py +16 -9
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/float_lower.py +21 -18
- fpy2-0.2.4/fpy2/strategies/if_simplify.py +78 -0
- fpy2-0.2.4/fpy2/strategies/invariant_hoist.py +121 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/iter_unfold.py +7 -2
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/loop_split.py +35 -2
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/loop_unroll.py +10 -1
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/neg_zero_unfold.py +13 -9
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/overflow_unfold.py +22 -29
- fpy2-0.2.4/fpy2/strategies/scale_hoist.py +117 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/sites.py +19 -3
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/special_unfold.py +17 -15
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/__init__.py +6 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/anf.py +12 -54
- fpy2-0.2.4/fpy2/transform/assert_elim.py +85 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/comp_to_loop.py +66 -43
- fpy2-0.2.4/fpy2/transform/const_fold.py +408 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/dead_code.py +4 -4
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/float_to_fixed.py +80 -110
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/for_bundling.py +4 -1
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/for_unroll.py +34 -12
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/func_inline.py +25 -6
- fpy2-0.2.4/fpy2/transform/hoist_invariant.py +581 -0
- fpy2-0.2.4/fpy2/transform/hoist_scale.py +477 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/hoistable.py +29 -182
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/if_bundling.py +4 -1
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/monomorphize.py +28 -26
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/path.py +8 -114
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/reduce_fusion.py +40 -44
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/rescale_fixed.py +60 -86
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/round_elim.py +39 -133
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/round_insert.py +2 -2
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/simplify.py +25 -11
- fpy2-0.2.4/fpy2/transform/simplify_if.py +502 -0
- fpy2-0.2.4/fpy2/transform/single_exit.py +224 -0
- fpy2-0.2.4/fpy2/transform/specialize.py +858 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/split_loop.py +107 -22
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/split_round.py +1 -1
- fpy2-0.2.4/fpy2/transform/statement_form.py +50 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/unfold_iter.py +10 -11
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/unfold_neg_zero.py +39 -73
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/unfold_overflow.py +105 -142
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/unfold_special.py +49 -80
- fpy2-0.2.4/fpy2/transform/unnest_context.py +187 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/utils.py +290 -184
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/while_bundling.py +4 -1
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/types.py +20 -14
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/utils/gensym.py +8 -4
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/utils/unionfind.py +2 -2
- fpy2-0.2.4/fpy2.egg-info/PKG-INFO +190 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2.egg-info/SOURCES.txt +29 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2.egg-info/requires.txt +4 -3
- {fpy2-0.2.3 → fpy2-0.2.4}/pyproject.toml +10 -4
- fpy2-0.2.3/PKG-INFO +0 -121
- fpy2-0.2.3/README.md +0 -91
- fpy2-0.2.3/fpy2/analysis/value_class.py +0 -781
- fpy2-0.2.3/fpy2/backend/cpp/unfold_round.py +0 -389
- fpy2-0.2.3/fpy2/transform/const_fold.py +0 -186
- fpy2-0.2.3/fpy2/transform/simplify_if.py +0 -181
- fpy2-0.2.3/fpy2/transform/specialize.py +0 -542
- fpy2-0.2.3/fpy2.egg-info/PKG-INFO +0 -121
- {fpy2-0.2.3 → fpy2-0.2.4}/LICENSE +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/analysis/call_graph.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/analysis/define_use.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/analysis/defs.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/analysis/escape.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/analysis/format_infer/double_round.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/analysis/live_vars.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/analysis/purity.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/analysis/reachability.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/analysis/syntax_check.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/ast/__init__.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/ast/formatter.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/ast/visitor.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/backend/backend.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/backend/cpp/__init__.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/backend/cpp/ops.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/backend/cpp/variables.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/env.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/fpc_context.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/frontend/__init__.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/frontend/fpc.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/frontend/parser.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/function.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/interpret/__init__.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/interpret/interpreter.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/interpret/value.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/libraries/__init__.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/libraries/base.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/libraries/core.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/libraries/eft.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/libraries/matrix.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/libraries/metrics.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/libraries/vector.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/module.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/__init__.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/context/__init__.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/context/context.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/context/efloat.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/context/exponential.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/context/fixed.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/context/format.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/context/ieee754.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/context/mp_fixed.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/context/mp_float.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/context/mpb_fixed.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/context/mpb_float.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/context/mps_float.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/context/real.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/context/sm_fixed.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/engine/__init__.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/engine/engine.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/engine/gmp.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/engine/real.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/format.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/globals.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/gmputils.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/native.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/number/__init__.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/number/flags.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/number/floats.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/number/reals.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/round.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/primitive.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/rewrite/__init__.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/rewrite/applier.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/rewrite/matcher.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/rewrite/pattern.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/rewrite/rewrite.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/rewrite/search.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/rewrite/subst.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/runner.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/anf.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/comp_lower.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/context_lift.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/free_var.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/func_inline.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/hoistable.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/iter_elim.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/mono.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/reduce_fusion.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/round_elim.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/round_insert.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/round_split.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/simple.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/copy_propagate.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/cursor.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/enumerate_elim.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/error.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/for_unpack.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/free_var_elim.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/iter_elim.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/lift_context.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/rename_target.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/subst_var.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/while_unroll.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/zip_elim.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/utils/__init__.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/utils/bits.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/utils/compare.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/utils/decorator.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/utils/default.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/utils/float_params.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/utils/fractions.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/utils/identifier.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/utils/inspect.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/utils/iterator.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/utils/loader.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/utils/location.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/utils/ordering.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/utils/string.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/utils/uninit.py +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2.egg-info/dependency_links.txt +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/fpy2.egg-info/top_level.txt +0 -0
- {fpy2-0.2.3 → fpy2-0.2.4}/setup.cfg +0 -0
fpy2-0.2.4/PKG-INFO
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: fpy2
|
|
3
|
+
Version: 0.2.4
|
|
4
|
+
Summary: An embedded DSL for numerical computing
|
|
5
|
+
Author-email: Brett Saiki <bsaiki@cs.washington.edu>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/bksaiki/fpy
|
|
8
|
+
Project-URL: Issues, https://github.com/bksaiki/fpy/issues
|
|
9
|
+
Project-URL: Documentation, https://fpy.readthedocs.io/
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Requires-Python: >=3.11
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
License-File: LICENSE
|
|
15
|
+
Requires-Dist: titanfp==0.1.2
|
|
16
|
+
Requires-Dist: gmpy2==2.3.1
|
|
17
|
+
Requires-Dist: numpy
|
|
18
|
+
Requires-Dist: z3-solver>=4.13
|
|
19
|
+
Provides-Extra: dev
|
|
20
|
+
Requires-Dist: pytest; extra == "dev"
|
|
21
|
+
Requires-Dist: pytest-xdist; extra == "dev"
|
|
22
|
+
Requires-Dist: hypothesis==6.135; extra == "dev"
|
|
23
|
+
Requires-Dist: mypy; extra == "dev"
|
|
24
|
+
Requires-Dist: ruff; extra == "dev"
|
|
25
|
+
Requires-Dist: build; extra == "dev"
|
|
26
|
+
Requires-Dist: twine; extra == "dev"
|
|
27
|
+
Requires-Dist: sphinx; extra == "dev"
|
|
28
|
+
Requires-Dist: sphinx-rtd-theme; extra == "dev"
|
|
29
|
+
Requires-Dist: sphinx-pyproject; extra == "dev"
|
|
30
|
+
Dynamic: license-file
|
|
31
|
+
|
|
32
|
+
# FPy
|
|
33
|
+
|
|
34
|
+
An embedded Python DSL for specifying and simulating numerical algorithms.
|
|
35
|
+
|
|
36
|
+
Important links:
|
|
37
|
+
- PyPI package: [fpy2](https://pypi.org/project/fpy2/)
|
|
38
|
+
- Documentation: [fpy.readthedocs.io](https://fpy.readthedocs.io/)
|
|
39
|
+
- GitHub: [fpy](https://github.com/bksaiki/fpy)
|
|
40
|
+
- Guide: [USAGE.md](docs/USAGE.md)
|
|
41
|
+
|
|
42
|
+
## Example
|
|
43
|
+
|
|
44
|
+
FPy is Python with explicit control of both the mathematics and
|
|
45
|
+
rounding: every operation is correctly rounded by the *rounding context*
|
|
46
|
+
it appears in, and contexts are ordinary values you can pass around —
|
|
47
|
+
including `fp.REAL`, which never rounds. Here is a blocked dot product:
|
|
48
|
+
the products are exact, each block of `K` elements is summed in a narrow
|
|
49
|
+
format, and the running total is `float32`.
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
import fpy2 as fp
|
|
53
|
+
|
|
54
|
+
@fp.fpy(ctx=fp.REAL)
|
|
55
|
+
def dot(xs: list[fp.Real], ys: list[fp.Real], K: int, block: fp.Context) -> fp.Real:
|
|
56
|
+
"""A blocked dot product: exact products, blocks of `K` summed in `block`.
|
|
57
|
+
The length of `xs` must be a multiple of `K`."""
|
|
58
|
+
assert len(xs) == len(ys)
|
|
59
|
+
acc = 0
|
|
60
|
+
for start in range(0, len(xs), K):
|
|
61
|
+
with block:
|
|
62
|
+
inner_acc = 0
|
|
63
|
+
for x, y in zip(xs[start:start + K], ys[start:start + K]):
|
|
64
|
+
with fp.REAL:
|
|
65
|
+
p = x * y # every product is exact ...
|
|
66
|
+
inner_acc += p # ... but block sums round to `block`
|
|
67
|
+
with fp.FP32:
|
|
68
|
+
acc += inner_acc # one fp32 addition per block
|
|
69
|
+
return acc
|
|
70
|
+
|
|
71
|
+
@fp.fpy(ctx=fp.REAL)
|
|
72
|
+
def dot_ref(xs: list[fp.Real], ys: list[fp.Real]) -> fp.Real:
|
|
73
|
+
"""The same dot product, with no rounding anywhere."""
|
|
74
|
+
return sum([x * y for x, y in zip(xs, ys)])
|
|
75
|
+
|
|
76
|
+
xs = ys = [0.1] * 4096
|
|
77
|
+
exact = dot_ref(xs, ys).as_rational() # the true value, as a Fraction
|
|
78
|
+
|
|
79
|
+
print(f'{"block":>6} {"format":>9} {"result":>11} {"rel. error":>11}')
|
|
80
|
+
for K, name, ctx in [(4096, 'float16', fp.FP16), (32, 'float16', fp.FP16),
|
|
81
|
+
(4096, 'bfloat16', fp.BF16), (32, 'bfloat16', fp.BF16),
|
|
82
|
+
(32, 'float32', fp.FP32)]:
|
|
83
|
+
r = dot(xs, ys, K, ctx)
|
|
84
|
+
err = abs(r.as_rational() - exact) / exact
|
|
85
|
+
print(f'{K:>6} {name:>9} {float(r):>11.6f} {float(err):>11.3%}')
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
which prints
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
block format result rel. error
|
|
92
|
+
4096 float16 32.000000 21.875%
|
|
93
|
+
32 float16 40.968750 0.021%
|
|
94
|
+
4096 bfloat16 4.000000 90.234%
|
|
95
|
+
32 bfloat16 40.250000 1.733%
|
|
96
|
+
32 float32 40.959972 0.000%
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
A flat `float16` accumulator stalls out once the running total dwarfs
|
|
100
|
+
the product being added to it; summing 32 elements at a time keeps the
|
|
101
|
+
error three orders of magnitude smaller.
|
|
102
|
+
|
|
103
|
+
See the [usage guide](docs/USAGE.md) for the language and the
|
|
104
|
+
[examples page](https://fpy.readthedocs.io/en/latest/example.html) for
|
|
105
|
+
more.
|
|
106
|
+
|
|
107
|
+
## Installation
|
|
108
|
+
|
|
109
|
+
FPy can be installed from PyPI with either `uv` or `pip`, or built from
|
|
110
|
+
source for development. The following instructions assume a `bash`-like
|
|
111
|
+
shell.
|
|
112
|
+
|
|
113
|
+
### Installing from PyPI
|
|
114
|
+
|
|
115
|
+
Requirements:
|
|
116
|
+
- Python 3.11 or later
|
|
117
|
+
|
|
118
|
+
To install the latest stable release of FPy, run:
|
|
119
|
+
```bash
|
|
120
|
+
uv pip install fpy2
|
|
121
|
+
```
|
|
122
|
+
or, with `pip`:
|
|
123
|
+
```bash
|
|
124
|
+
pip install fpy2
|
|
125
|
+
```
|
|
126
|
+
The Triton backend also needs PyTorch, Triton and a GPU: install `fpy2[triton]`.
|
|
127
|
+
|
|
128
|
+
### Installing from source
|
|
129
|
+
|
|
130
|
+
Requirements:
|
|
131
|
+
- Python 3.11 or later
|
|
132
|
+
- `make`
|
|
133
|
+
|
|
134
|
+
#### With `uv` (preferred)
|
|
135
|
+
|
|
136
|
+
[uv](https://docs.astral.sh/uv/) is the recommended development
|
|
137
|
+
workflow — it handles the virtual environment and dependency
|
|
138
|
+
installation in a single step:
|
|
139
|
+
```bash
|
|
140
|
+
uv sync
|
|
141
|
+
```
|
|
142
|
+
This creates `.venv/` and installs FPy in editable mode along with the
|
|
143
|
+
`dev` dependency group, pinned by `uv.lock`. Rerun it to reset `.venv/` to
|
|
144
|
+
the lockfile; it removes anything installed by hand. Activate the
|
|
145
|
+
environment with
|
|
146
|
+
```bash
|
|
147
|
+
source .venv/bin/activate
|
|
148
|
+
```
|
|
149
|
+
or prefix individual commands with `uv run` (e.g. `uv run pytest tests/unit`).
|
|
150
|
+
|
|
151
|
+
#### With `pip` (legacy)
|
|
152
|
+
|
|
153
|
+
This path is preserved for compatibility with existing tooling; new
|
|
154
|
+
contributors should prefer `uv` above.
|
|
155
|
+
|
|
156
|
+
If you do not have a Python virtual environment,
|
|
157
|
+
create one using
|
|
158
|
+
```bash
|
|
159
|
+
python3 -m venv .venv/
|
|
160
|
+
```
|
|
161
|
+
and activate it using
|
|
162
|
+
```bash
|
|
163
|
+
source .venv/bin/activate
|
|
164
|
+
```
|
|
165
|
+
To install an instance of FPy for development, run:
|
|
166
|
+
```bash
|
|
167
|
+
pip install -e .[dev]
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
To uninstall FPy, run:
|
|
171
|
+
```bash
|
|
172
|
+
pip uninstall fpy2
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Testing
|
|
176
|
+
|
|
177
|
+
There are a number of tests that can be run through
|
|
178
|
+
the `Makefile` including
|
|
179
|
+
```bash
|
|
180
|
+
make lint
|
|
181
|
+
```
|
|
182
|
+
to ensure formatting and type safety;
|
|
183
|
+
```bash
|
|
184
|
+
make unittest
|
|
185
|
+
```
|
|
186
|
+
to run the unit tests;
|
|
187
|
+
```bash
|
|
188
|
+
make infratest
|
|
189
|
+
```
|
|
190
|
+
to run the infrastructure tests.
|
fpy2-0.2.4/README.md
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# FPy
|
|
2
|
+
|
|
3
|
+
An embedded Python DSL for specifying and simulating numerical algorithms.
|
|
4
|
+
|
|
5
|
+
Important links:
|
|
6
|
+
- PyPI package: [fpy2](https://pypi.org/project/fpy2/)
|
|
7
|
+
- Documentation: [fpy.readthedocs.io](https://fpy.readthedocs.io/)
|
|
8
|
+
- GitHub: [fpy](https://github.com/bksaiki/fpy)
|
|
9
|
+
- Guide: [USAGE.md](docs/USAGE.md)
|
|
10
|
+
|
|
11
|
+
## Example
|
|
12
|
+
|
|
13
|
+
FPy is Python with explicit control of both the mathematics and
|
|
14
|
+
rounding: every operation is correctly rounded by the *rounding context*
|
|
15
|
+
it appears in, and contexts are ordinary values you can pass around —
|
|
16
|
+
including `fp.REAL`, which never rounds. Here is a blocked dot product:
|
|
17
|
+
the products are exact, each block of `K` elements is summed in a narrow
|
|
18
|
+
format, and the running total is `float32`.
|
|
19
|
+
|
|
20
|
+
```python
|
|
21
|
+
import fpy2 as fp
|
|
22
|
+
|
|
23
|
+
@fp.fpy(ctx=fp.REAL)
|
|
24
|
+
def dot(xs: list[fp.Real], ys: list[fp.Real], K: int, block: fp.Context) -> fp.Real:
|
|
25
|
+
"""A blocked dot product: exact products, blocks of `K` summed in `block`.
|
|
26
|
+
The length of `xs` must be a multiple of `K`."""
|
|
27
|
+
assert len(xs) == len(ys)
|
|
28
|
+
acc = 0
|
|
29
|
+
for start in range(0, len(xs), K):
|
|
30
|
+
with block:
|
|
31
|
+
inner_acc = 0
|
|
32
|
+
for x, y in zip(xs[start:start + K], ys[start:start + K]):
|
|
33
|
+
with fp.REAL:
|
|
34
|
+
p = x * y # every product is exact ...
|
|
35
|
+
inner_acc += p # ... but block sums round to `block`
|
|
36
|
+
with fp.FP32:
|
|
37
|
+
acc += inner_acc # one fp32 addition per block
|
|
38
|
+
return acc
|
|
39
|
+
|
|
40
|
+
@fp.fpy(ctx=fp.REAL)
|
|
41
|
+
def dot_ref(xs: list[fp.Real], ys: list[fp.Real]) -> fp.Real:
|
|
42
|
+
"""The same dot product, with no rounding anywhere."""
|
|
43
|
+
return sum([x * y for x, y in zip(xs, ys)])
|
|
44
|
+
|
|
45
|
+
xs = ys = [0.1] * 4096
|
|
46
|
+
exact = dot_ref(xs, ys).as_rational() # the true value, as a Fraction
|
|
47
|
+
|
|
48
|
+
print(f'{"block":>6} {"format":>9} {"result":>11} {"rel. error":>11}')
|
|
49
|
+
for K, name, ctx in [(4096, 'float16', fp.FP16), (32, 'float16', fp.FP16),
|
|
50
|
+
(4096, 'bfloat16', fp.BF16), (32, 'bfloat16', fp.BF16),
|
|
51
|
+
(32, 'float32', fp.FP32)]:
|
|
52
|
+
r = dot(xs, ys, K, ctx)
|
|
53
|
+
err = abs(r.as_rational() - exact) / exact
|
|
54
|
+
print(f'{K:>6} {name:>9} {float(r):>11.6f} {float(err):>11.3%}')
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
which prints
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
block format result rel. error
|
|
61
|
+
4096 float16 32.000000 21.875%
|
|
62
|
+
32 float16 40.968750 0.021%
|
|
63
|
+
4096 bfloat16 4.000000 90.234%
|
|
64
|
+
32 bfloat16 40.250000 1.733%
|
|
65
|
+
32 float32 40.959972 0.000%
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
A flat `float16` accumulator stalls out once the running total dwarfs
|
|
69
|
+
the product being added to it; summing 32 elements at a time keeps the
|
|
70
|
+
error three orders of magnitude smaller.
|
|
71
|
+
|
|
72
|
+
See the [usage guide](docs/USAGE.md) for the language and the
|
|
73
|
+
[examples page](https://fpy.readthedocs.io/en/latest/example.html) for
|
|
74
|
+
more.
|
|
75
|
+
|
|
76
|
+
## Installation
|
|
77
|
+
|
|
78
|
+
FPy can be installed from PyPI with either `uv` or `pip`, or built from
|
|
79
|
+
source for development. The following instructions assume a `bash`-like
|
|
80
|
+
shell.
|
|
81
|
+
|
|
82
|
+
### Installing from PyPI
|
|
83
|
+
|
|
84
|
+
Requirements:
|
|
85
|
+
- Python 3.11 or later
|
|
86
|
+
|
|
87
|
+
To install the latest stable release of FPy, run:
|
|
88
|
+
```bash
|
|
89
|
+
uv pip install fpy2
|
|
90
|
+
```
|
|
91
|
+
or, with `pip`:
|
|
92
|
+
```bash
|
|
93
|
+
pip install fpy2
|
|
94
|
+
```
|
|
95
|
+
The Triton backend also needs PyTorch, Triton and a GPU: install `fpy2[triton]`.
|
|
96
|
+
|
|
97
|
+
### Installing from source
|
|
98
|
+
|
|
99
|
+
Requirements:
|
|
100
|
+
- Python 3.11 or later
|
|
101
|
+
- `make`
|
|
102
|
+
|
|
103
|
+
#### With `uv` (preferred)
|
|
104
|
+
|
|
105
|
+
[uv](https://docs.astral.sh/uv/) is the recommended development
|
|
106
|
+
workflow — it handles the virtual environment and dependency
|
|
107
|
+
installation in a single step:
|
|
108
|
+
```bash
|
|
109
|
+
uv sync
|
|
110
|
+
```
|
|
111
|
+
This creates `.venv/` and installs FPy in editable mode along with the
|
|
112
|
+
`dev` dependency group, pinned by `uv.lock`. Rerun it to reset `.venv/` to
|
|
113
|
+
the lockfile; it removes anything installed by hand. Activate the
|
|
114
|
+
environment with
|
|
115
|
+
```bash
|
|
116
|
+
source .venv/bin/activate
|
|
117
|
+
```
|
|
118
|
+
or prefix individual commands with `uv run` (e.g. `uv run pytest tests/unit`).
|
|
119
|
+
|
|
120
|
+
#### With `pip` (legacy)
|
|
121
|
+
|
|
122
|
+
This path is preserved for compatibility with existing tooling; new
|
|
123
|
+
contributors should prefer `uv` above.
|
|
124
|
+
|
|
125
|
+
If you do not have a Python virtual environment,
|
|
126
|
+
create one using
|
|
127
|
+
```bash
|
|
128
|
+
python3 -m venv .venv/
|
|
129
|
+
```
|
|
130
|
+
and activate it using
|
|
131
|
+
```bash
|
|
132
|
+
source .venv/bin/activate
|
|
133
|
+
```
|
|
134
|
+
To install an instance of FPy for development, run:
|
|
135
|
+
```bash
|
|
136
|
+
pip install -e .[dev]
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
To uninstall FPy, run:
|
|
140
|
+
```bash
|
|
141
|
+
pip uninstall fpy2
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Testing
|
|
145
|
+
|
|
146
|
+
There are a number of tests that can be run through
|
|
147
|
+
the `Makefile` including
|
|
148
|
+
```bash
|
|
149
|
+
make lint
|
|
150
|
+
```
|
|
151
|
+
to ensure formatting and type safety;
|
|
152
|
+
```bash
|
|
153
|
+
make unittest
|
|
154
|
+
```
|
|
155
|
+
to run the unit tests;
|
|
156
|
+
```bash
|
|
157
|
+
make infratest
|
|
158
|
+
```
|
|
159
|
+
to run the infrastructure tests.
|
|
@@ -9,6 +9,7 @@ from .array_size import (
|
|
|
9
9
|
ListSize,
|
|
10
10
|
TupleSize,
|
|
11
11
|
concrete_size,
|
|
12
|
+
static_trip_count,
|
|
12
13
|
)
|
|
13
14
|
from .call_graph import CallGraph, CallGraphAnalysis, CallGraphError
|
|
14
15
|
from .context_use import (
|
|
@@ -17,13 +18,16 @@ from .context_use import (
|
|
|
17
18
|
ContextUse,
|
|
18
19
|
ContextUseAnalysis,
|
|
19
20
|
ContextUseSite,
|
|
21
|
+
PartialContext,
|
|
22
|
+
ScopeContext,
|
|
20
23
|
)
|
|
21
24
|
from .define_use import DefCtx, DefineUse, DefineUseAnalysis, UseSite
|
|
22
25
|
from .defs import DefAnalysis
|
|
23
26
|
from .escape import Escape, EscapeSummary
|
|
24
27
|
from .format_infer import FormatAnalysis, FormatInfer
|
|
28
|
+
from .hoistability import Hoistability, HoistabilityAnalysis
|
|
25
29
|
from .live_vars import LiveVars
|
|
26
|
-
from .partial_eval import PartialEval, PartialEvalInfo
|
|
30
|
+
from .partial_eval import PartialEval, PartialEvalInfo, base_env
|
|
27
31
|
from .purity import Purity
|
|
28
32
|
from .reachability import Reachability
|
|
29
33
|
from .reaching_defs import (
|
|
@@ -53,9 +53,7 @@ Equality rather than inclusion is deliberate. Each place denotes exactly one
|
|
|
53
53
|
region and distinct regions are disjoint — Steensgaard-style, where a
|
|
54
54
|
subset-based solver would give each place an overlapping points-to *set* — so
|
|
55
55
|
different regions never alias and the same region may. That over-approximates,
|
|
56
|
-
the safe direction for every consumer, and it is adequate here
|
|
57
|
-
test corpus, only three merges anywhere lose precision against a subset-based
|
|
58
|
-
solver.
|
|
56
|
+
the safe direction for every consumer, and it is adequate here.
|
|
59
57
|
|
|
60
58
|
An expression kind not in the table is handled conservatively: it gets its own
|
|
61
59
|
allocation site, and every list-carrying variable inside it is marked shared
|
|
@@ -350,6 +348,9 @@ class _Regions:
|
|
|
350
348
|
def sites_at(self, c: Region) -> frozenset[AllocSite]:
|
|
351
349
|
return frozenset(self._sites.get(self.find(c), ()))
|
|
352
350
|
|
|
351
|
+
def is_slot(self, c: Region) -> bool:
|
|
352
|
+
return self._slots.get(self.find(c), 0) > 0
|
|
353
|
+
|
|
353
354
|
def referrers(self, c: Region) -> int:
|
|
354
355
|
root = self.find(c)
|
|
355
356
|
return len(self._names.get(root, ())) + self._slots.get(root, 0)
|
|
@@ -402,6 +403,8 @@ class AliasAnalysis:
|
|
|
402
403
|
Attributes:
|
|
403
404
|
sites: every list allocation, plus one per nested parameter list.
|
|
404
405
|
written_regions: regions an ``xs[i] = e`` here stores into.
|
|
406
|
+
stored_regions: regions whose cells a store here replaces:
|
|
407
|
+
``xss[i][j] = e`` replaces a row's, not ``xss``'s.
|
|
405
408
|
slot_replaced: element regions an ``xss[i] = <list>`` replaces.
|
|
406
409
|
returned_levels: regions the ``return``s hand back, by depth.
|
|
407
410
|
consumed_defs: per region, definitions whose value *moves* into a
|
|
@@ -414,6 +417,7 @@ class AliasAnalysis:
|
|
|
414
417
|
_by_expr: dict[Expr, Region]
|
|
415
418
|
_site_region: dict[AllocSite, Region]
|
|
416
419
|
written_regions: set[Region] = field(default_factory=set)
|
|
420
|
+
stored_regions: set[Region] = field(default_factory=set)
|
|
417
421
|
slot_replaced: set[Region] = field(default_factory=set)
|
|
418
422
|
returned_levels: list[set[Region]] = field(default_factory=list)
|
|
419
423
|
consumed_defs: dict[Region, set[Definition]] = field(default_factory=dict)
|
|
@@ -516,6 +520,17 @@ class AliasAnalysis:
|
|
|
516
520
|
"""The allocations that may live in *region*."""
|
|
517
521
|
return frozenset() if region is None else self._regions.sites_at(region)
|
|
518
522
|
|
|
523
|
+
def inside_at(self, region: Region) -> bool:
|
|
524
|
+
"""Whether *region* is a place *within* a container — a list's elements,
|
|
525
|
+
a tuple's field — rather than a place a name denotes.
|
|
526
|
+
|
|
527
|
+
A container holds many elements, so such a region stands for one list
|
|
528
|
+
per element of its container, however few allocations reach it. That
|
|
529
|
+
is the difference between "may be the same list", which a region
|
|
530
|
+
answers, and "is exactly one list", which it does not.
|
|
531
|
+
"""
|
|
532
|
+
return self._regions.is_slot(region)
|
|
533
|
+
|
|
519
534
|
def is_shared(self, site: AllocSite) -> bool:
|
|
520
535
|
"""Whether more than one place may refer to *site*."""
|
|
521
536
|
return self._regions.referrers(self._site_region[site]) > 1
|
|
@@ -576,6 +591,12 @@ class AliasAnalysis:
|
|
|
576
591
|
return False
|
|
577
592
|
return self._regions.find(ca) is self._regions.find(cb)
|
|
578
593
|
|
|
594
|
+
def may_change(self, d: Definition) -> bool:
|
|
595
|
+
"""Whether the list *d* names may have an element replaced, through
|
|
596
|
+
any name here or by a call it is handed to."""
|
|
597
|
+
r = self.region_of(d)
|
|
598
|
+
return r is None or r in self.stored_regions or self.escapes_at(r)
|
|
599
|
+
|
|
579
600
|
|
|
580
601
|
class _EscapeVars(DefaultVisitor):
|
|
581
602
|
"""Marks every list-carrying variable inside an expression as shared outward.
|
|
@@ -633,6 +654,7 @@ class _Builder(DefaultVisitor):
|
|
|
633
654
|
facts = _RegionFacts(alias, self.def_use)
|
|
634
655
|
facts._visit_function(self.func, None)
|
|
635
656
|
alias.written_regions = facts.written
|
|
657
|
+
alias.stored_regions = facts.stored
|
|
636
658
|
alias.slot_replaced = facts.slot_replaced
|
|
637
659
|
alias.returned_levels = facts.returned_levels
|
|
638
660
|
alias.consumed_defs = facts.consumed
|
|
@@ -929,6 +951,7 @@ class _RegionFacts(DefaultVisitor):
|
|
|
929
951
|
self.alias = alias
|
|
930
952
|
self.def_use = def_use
|
|
931
953
|
self.written: set[Region] = set()
|
|
954
|
+
self.stored: set[Region] = set()
|
|
932
955
|
self.slot_replaced: set[Region] = set()
|
|
933
956
|
self.returned_levels: list[set[Region]] = []
|
|
934
957
|
self.consumed: dict[Region, set[Definition]] = {}
|
|
@@ -947,6 +970,9 @@ class _RegionFacts(DefaultVisitor):
|
|
|
947
970
|
if isinstance(d, AssignDef) and isinstance(d.site, IndexedAssign):
|
|
948
971
|
if (r := alias.region_of(d)) is not None:
|
|
949
972
|
self.written.add(r)
|
|
973
|
+
depth = len(d.site.indices) - 1
|
|
974
|
+
if (r := alias.region_of(d, depth)) is not None:
|
|
975
|
+
self.stored.add(r)
|
|
950
976
|
|
|
951
977
|
def _visit_block(self, block: StmtBlock, ctx):
|
|
952
978
|
outer, self._siblings = self._siblings, set(block.stmts)
|