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.
Files changed (225) hide show
  1. fpy2-0.2.4/PKG-INFO +190 -0
  2. fpy2-0.2.4/README.md +159 -0
  3. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/__init__.py +1 -0
  4. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/analysis/__init__.py +5 -1
  5. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/analysis/alias.py +29 -3
  6. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/analysis/array_size.py +251 -73
  7. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/analysis/context_use.py +84 -10
  8. fpy2-0.2.4/fpy2/analysis/digit_bound/__init__.py +34 -0
  9. fpy2-0.2.4/fpy2/analysis/digit_bound/infer.py +1778 -0
  10. fpy2-0.2.4/fpy2/analysis/digit_bound/solver.py +419 -0
  11. fpy2-0.2.4/fpy2/analysis/digit_bound/store.py +265 -0
  12. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/analysis/format_infer/__init__.py +4 -0
  13. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/analysis/format_infer/analysis.py +657 -166
  14. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/analysis/format_infer/format.py +22 -8
  15. fpy2-0.2.4/fpy2/analysis/hoistability.py +228 -0
  16. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/analysis/partial_eval.py +7 -7
  17. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/analysis/reaching_defs.py +15 -1
  18. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/analysis/storage_infer.py +103 -17
  19. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/analysis/type_infer.py +4 -4
  20. fpy2-0.2.4/fpy2/analysis/value_class.py +1975 -0
  21. fpy2-0.2.4/fpy2/ast/accessors.py +149 -0
  22. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/ast/fpyast.py +16 -6
  23. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/backend/__init__.py +3 -0
  24. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/backend/cpp/compiler.py +187 -73
  25. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/backend/cpp/emitter.py +769 -259
  26. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/backend/cpp/storage.py +23 -6
  27. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/backend/cpp/target.py +58 -30
  28. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/backend/cpp/types.py +16 -0
  29. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/backend/cpp/unbox.py +8 -1
  30. fpy2-0.2.4/fpy2/backend/cpp/unfold_round.py +72 -0
  31. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/backend/cpp/utils.py +4 -1
  32. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/backend/fpc.py +2 -2
  33. fpy2-0.2.4/fpy2/backend/triton/__init__.py +47 -0
  34. fpy2-0.2.4/fpy2/backend/triton/compiler.py +167 -0
  35. fpy2-0.2.4/fpy2/backend/triton/emitter.py +2895 -0
  36. fpy2-0.2.4/fpy2/backend/triton/launcher.py +265 -0
  37. fpy2-0.2.4/fpy2/backend/triton/normalize.py +131 -0
  38. fpy2-0.2.4/fpy2/backend/triton/split_names.py +84 -0
  39. fpy2-0.2.4/fpy2/backend/triton/storage.py +196 -0
  40. fpy2-0.2.4/fpy2/backend/triton/target.py +258 -0
  41. fpy2-0.2.4/fpy2/backend/triton/types.py +92 -0
  42. fpy2-0.2.4/fpy2/backend/triton/unfold_round.py +109 -0
  43. fpy2-0.2.4/fpy2/backend/triton/vectorize.py +471 -0
  44. fpy2-0.2.4/fpy2/backend/unfold_round.py +308 -0
  45. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/decorator.py +26 -3
  46. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/interpret/byte.py +37 -2
  47. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/ops.py +11 -19
  48. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/__init__.py +26 -0
  49. fpy2-0.2.4/fpy2/strategies/assert_elim.py +55 -0
  50. fpy2-0.2.4/fpy2/strategies/exit_single.py +78 -0
  51. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/fixed_rescale.py +16 -9
  52. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/float_lower.py +21 -18
  53. fpy2-0.2.4/fpy2/strategies/if_simplify.py +78 -0
  54. fpy2-0.2.4/fpy2/strategies/invariant_hoist.py +121 -0
  55. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/iter_unfold.py +7 -2
  56. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/loop_split.py +35 -2
  57. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/loop_unroll.py +10 -1
  58. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/neg_zero_unfold.py +13 -9
  59. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/overflow_unfold.py +22 -29
  60. fpy2-0.2.4/fpy2/strategies/scale_hoist.py +117 -0
  61. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/sites.py +19 -3
  62. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/special_unfold.py +17 -15
  63. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/__init__.py +6 -0
  64. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/anf.py +12 -54
  65. fpy2-0.2.4/fpy2/transform/assert_elim.py +85 -0
  66. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/comp_to_loop.py +66 -43
  67. fpy2-0.2.4/fpy2/transform/const_fold.py +408 -0
  68. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/dead_code.py +4 -4
  69. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/float_to_fixed.py +80 -110
  70. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/for_bundling.py +4 -1
  71. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/for_unroll.py +34 -12
  72. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/func_inline.py +25 -6
  73. fpy2-0.2.4/fpy2/transform/hoist_invariant.py +581 -0
  74. fpy2-0.2.4/fpy2/transform/hoist_scale.py +477 -0
  75. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/hoistable.py +29 -182
  76. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/if_bundling.py +4 -1
  77. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/monomorphize.py +28 -26
  78. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/path.py +8 -114
  79. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/reduce_fusion.py +40 -44
  80. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/rescale_fixed.py +60 -86
  81. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/round_elim.py +39 -133
  82. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/round_insert.py +2 -2
  83. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/simplify.py +25 -11
  84. fpy2-0.2.4/fpy2/transform/simplify_if.py +502 -0
  85. fpy2-0.2.4/fpy2/transform/single_exit.py +224 -0
  86. fpy2-0.2.4/fpy2/transform/specialize.py +858 -0
  87. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/split_loop.py +107 -22
  88. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/split_round.py +1 -1
  89. fpy2-0.2.4/fpy2/transform/statement_form.py +50 -0
  90. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/unfold_iter.py +10 -11
  91. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/unfold_neg_zero.py +39 -73
  92. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/unfold_overflow.py +105 -142
  93. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/unfold_special.py +49 -80
  94. fpy2-0.2.4/fpy2/transform/unnest_context.py +187 -0
  95. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/utils.py +290 -184
  96. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/while_bundling.py +4 -1
  97. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/types.py +20 -14
  98. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/utils/gensym.py +8 -4
  99. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/utils/unionfind.py +2 -2
  100. fpy2-0.2.4/fpy2.egg-info/PKG-INFO +190 -0
  101. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2.egg-info/SOURCES.txt +29 -0
  102. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2.egg-info/requires.txt +4 -3
  103. {fpy2-0.2.3 → fpy2-0.2.4}/pyproject.toml +10 -4
  104. fpy2-0.2.3/PKG-INFO +0 -121
  105. fpy2-0.2.3/README.md +0 -91
  106. fpy2-0.2.3/fpy2/analysis/value_class.py +0 -781
  107. fpy2-0.2.3/fpy2/backend/cpp/unfold_round.py +0 -389
  108. fpy2-0.2.3/fpy2/transform/const_fold.py +0 -186
  109. fpy2-0.2.3/fpy2/transform/simplify_if.py +0 -181
  110. fpy2-0.2.3/fpy2/transform/specialize.py +0 -542
  111. fpy2-0.2.3/fpy2.egg-info/PKG-INFO +0 -121
  112. {fpy2-0.2.3 → fpy2-0.2.4}/LICENSE +0 -0
  113. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/analysis/call_graph.py +0 -0
  114. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/analysis/define_use.py +0 -0
  115. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/analysis/defs.py +0 -0
  116. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/analysis/escape.py +0 -0
  117. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/analysis/format_infer/double_round.py +0 -0
  118. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/analysis/live_vars.py +0 -0
  119. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/analysis/purity.py +0 -0
  120. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/analysis/reachability.py +0 -0
  121. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/analysis/syntax_check.py +0 -0
  122. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/ast/__init__.py +0 -0
  123. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/ast/formatter.py +0 -0
  124. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/ast/visitor.py +0 -0
  125. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/backend/backend.py +0 -0
  126. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/backend/cpp/__init__.py +0 -0
  127. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/backend/cpp/ops.py +0 -0
  128. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/backend/cpp/variables.py +0 -0
  129. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/env.py +0 -0
  130. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/fpc_context.py +0 -0
  131. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/frontend/__init__.py +0 -0
  132. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/frontend/fpc.py +0 -0
  133. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/frontend/parser.py +0 -0
  134. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/function.py +0 -0
  135. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/interpret/__init__.py +0 -0
  136. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/interpret/interpreter.py +0 -0
  137. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/interpret/value.py +0 -0
  138. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/libraries/__init__.py +0 -0
  139. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/libraries/base.py +0 -0
  140. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/libraries/core.py +0 -0
  141. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/libraries/eft.py +0 -0
  142. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/libraries/matrix.py +0 -0
  143. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/libraries/metrics.py +0 -0
  144. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/libraries/vector.py +0 -0
  145. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/module.py +0 -0
  146. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/__init__.py +0 -0
  147. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/context/__init__.py +0 -0
  148. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/context/context.py +0 -0
  149. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/context/efloat.py +0 -0
  150. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/context/exponential.py +0 -0
  151. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/context/fixed.py +0 -0
  152. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/context/format.py +0 -0
  153. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/context/ieee754.py +0 -0
  154. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/context/mp_fixed.py +0 -0
  155. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/context/mp_float.py +0 -0
  156. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/context/mpb_fixed.py +0 -0
  157. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/context/mpb_float.py +0 -0
  158. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/context/mps_float.py +0 -0
  159. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/context/real.py +0 -0
  160. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/context/sm_fixed.py +0 -0
  161. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/engine/__init__.py +0 -0
  162. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/engine/engine.py +0 -0
  163. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/engine/gmp.py +0 -0
  164. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/engine/real.py +0 -0
  165. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/format.py +0 -0
  166. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/globals.py +0 -0
  167. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/gmputils.py +0 -0
  168. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/native.py +0 -0
  169. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/number/__init__.py +0 -0
  170. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/number/flags.py +0 -0
  171. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/number/floats.py +0 -0
  172. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/number/reals.py +0 -0
  173. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/number/round.py +0 -0
  174. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/primitive.py +0 -0
  175. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/rewrite/__init__.py +0 -0
  176. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/rewrite/applier.py +0 -0
  177. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/rewrite/matcher.py +0 -0
  178. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/rewrite/pattern.py +0 -0
  179. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/rewrite/rewrite.py +0 -0
  180. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/rewrite/search.py +0 -0
  181. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/rewrite/subst.py +0 -0
  182. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/runner.py +0 -0
  183. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/anf.py +0 -0
  184. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/comp_lower.py +0 -0
  185. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/context_lift.py +0 -0
  186. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/free_var.py +0 -0
  187. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/func_inline.py +0 -0
  188. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/hoistable.py +0 -0
  189. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/iter_elim.py +0 -0
  190. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/mono.py +0 -0
  191. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/reduce_fusion.py +0 -0
  192. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/round_elim.py +0 -0
  193. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/round_insert.py +0 -0
  194. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/round_split.py +0 -0
  195. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/strategies/simple.py +0 -0
  196. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/copy_propagate.py +0 -0
  197. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/cursor.py +0 -0
  198. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/enumerate_elim.py +0 -0
  199. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/error.py +0 -0
  200. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/for_unpack.py +0 -0
  201. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/free_var_elim.py +0 -0
  202. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/iter_elim.py +0 -0
  203. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/lift_context.py +0 -0
  204. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/rename_target.py +0 -0
  205. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/subst_var.py +0 -0
  206. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/while_unroll.py +0 -0
  207. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/transform/zip_elim.py +0 -0
  208. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/utils/__init__.py +0 -0
  209. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/utils/bits.py +0 -0
  210. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/utils/compare.py +0 -0
  211. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/utils/decorator.py +0 -0
  212. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/utils/default.py +0 -0
  213. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/utils/float_params.py +0 -0
  214. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/utils/fractions.py +0 -0
  215. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/utils/identifier.py +0 -0
  216. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/utils/inspect.py +0 -0
  217. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/utils/iterator.py +0 -0
  218. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/utils/loader.py +0 -0
  219. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/utils/location.py +0 -0
  220. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/utils/ordering.py +0 -0
  221. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/utils/string.py +0 -0
  222. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2/utils/uninit.py +0 -0
  223. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2.egg-info/dependency_links.txt +0 -0
  224. {fpy2-0.2.3 → fpy2-0.2.4}/fpy2.egg-info/top_level.txt +0 -0
  225. {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.
@@ -36,6 +36,7 @@ from .backend import (
36
36
  Backend,
37
37
  CppCompiler,
38
38
  FPCoreCompiler,
39
+ TritonCompiler,
39
40
  )
40
41
 
41
42
  # runtime support
@@ -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: measured over the
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)