numbox 0.2.3__py3-none-any.whl → 0.2.5__py3-none-any.whl

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.

Potentially problematic release.


This version of numbox might be problematic. Click here for more details.

numbox/__init__.py CHANGED
@@ -1 +1 @@
1
- __version__ = '0.2.3'
1
+ __version__ = '0.2.5'
@@ -1,6 +1,7 @@
1
1
  from hashlib import md5
2
- from inspect import getfile, getmodule
2
+ from inspect import getfile, getmodule, getsource
3
3
  from io import StringIO
4
+ from itertools import chain
4
5
  from numba import njit, typeof
5
6
  from numba.core.types import Type
6
7
  from typing import Any, Callable, NamedTuple, Optional, Sequence, Union
@@ -14,13 +15,32 @@ def _file_anchor():
14
15
  raise NotImplementedError
15
16
 
16
17
 
17
- class End(NamedTuple):
18
+ _nodes_names = set()
19
+
20
+
21
+ class _End(NamedTuple):
18
22
  name: str
19
23
  init_value: Any
20
24
  ty: Optional[type | Type] = None
21
25
 
22
26
 
23
- class Derived(NamedTuple):
27
+ def _new(cls, super_proxy, *args, **kwargs):
28
+ name = kwargs.get("name")
29
+ assert name, "`name` key-word argument has not been provided"
30
+ if name in _nodes_names:
31
+ raise ValueError(f"Node '{name}' has already been defined on this graph. Pick a different name.")
32
+ _nodes_names.add(name)
33
+ return super_proxy.__new__(cls, *args, **kwargs)
34
+
35
+
36
+ class End(_End):
37
+ __slots__ = ()
38
+
39
+ def __new__(cls, *args, **kwargs):
40
+ return _new(cls, super(), *args, **kwargs)
41
+
42
+
43
+ class _Derived(NamedTuple):
24
44
  name: str
25
45
  init_value: Any
26
46
  derive: Callable
@@ -28,24 +48,37 @@ class Derived(NamedTuple):
28
48
  ty: Optional[type | Type] = None
29
49
 
30
50
 
51
+ class Derived(_Derived):
52
+ __slots__ = ()
53
+
54
+ def __new__(cls, *args, **kwargs):
55
+ return _new(cls, super(), *args, **kwargs)
56
+
57
+
31
58
  SpecTy = Derived | End
32
59
 
33
60
 
34
- def _input_line(input_: End, ns):
61
+ def _input_line(input_: End, ns: dict, initializers: dict):
35
62
  name_ = input_.name
36
63
  init_ = input_.init_value
64
+ init_name = f"{name_}_init"
65
+ ns[init_name] = init_
66
+ initializers[init_name] = init_
37
67
  ty_ = input_.ty
38
68
  if ty_ is not None:
39
69
  type_name = f"{name_}_ty"
40
70
  ns[type_name] = ty_
41
- return f"""{name_} = ll_make_work("{name_}", {init_}, (), None, {type_name})"""
42
- return f"""{name_} = ll_make_work("{name_}", {init_}, (), None)"""
71
+ return f"""{name_} = ll_make_work("{name_}", {init_name}, (), None, {type_name})"""
72
+ return f"""{name_} = ll_make_work("{name_}", {init_name}, (), None)"""
43
73
 
44
74
 
45
75
  def get_ty(spec_):
46
76
  return spec_.ty or typeof(spec_.init_value)
47
77
 
48
78
 
79
+ _derive_funcs = {}
80
+
81
+
49
82
  def _derived_cres(ty, sources: Sequence[End], derive, jit_options=None):
50
83
  jit_options = jit_options if jit_options is not None else {}
51
84
  sources_ty = []
@@ -54,20 +87,28 @@ def _derived_cres(ty, sources: Sequence[End], derive, jit_options=None):
54
87
  sources_ty.append(source_ty)
55
88
  derive_sig = ty(*sources_ty)
56
89
  derive_cres = cres(derive_sig, **jit_options)(derive)
90
+ _derive_funcs[id(derive_cres)] = derive
57
91
  return derive_cres
58
92
 
59
93
 
60
- def _derived_line(derived_: Derived, ns: dict, _make_args: list, jit_options=None):
94
+ def _derived_line(
95
+ derived_: Derived, ns: dict, initializers: dict, derive_hashes: list, _make_args: list, jit_options=None
96
+ ):
61
97
  name_ = derived_.name
62
98
  init_ = derived_.init_value
63
99
  sources_ = ", ".join([s.name for s in derived_.sources])
64
100
  sources_ = sources_ + ", " if "," not in sources_ else sources_
65
101
  ty_ = get_ty(derived_)
66
- derive_ = _derived_cres(ty_, derived_.sources, derived_.derive, jit_options)
102
+ derive_func = derived_.derive
103
+ derive_hashes.append(md5(getsource(derive_func).encode("utf-8")).hexdigest())
104
+ derive_ = _derived_cres(ty_, derived_.sources, derive_func, jit_options)
67
105
  derive_name = f"{name_}_derive"
106
+ init_name = f"{name_}_init"
68
107
  _make_args.append(derive_name)
69
108
  ns[derive_name] = derive_
70
- return f"""{name_} = ll_make_work("{name_}", {init_}, ({sources_}), {derive_name})"""
109
+ ns[init_name] = init_
110
+ initializers[init_name] = init_
111
+ return f"""{name_} = ll_make_work("{name_}", {init_name}, ({sources_}), {derive_name})"""
71
112
 
72
113
 
73
114
  def _verify_access_nodes(
@@ -102,17 +143,20 @@ def make_graph(
102
143
  }
103
144
  _make_args = []
104
145
  code_txt = StringIO()
146
+ initializers = {}
147
+ derive_hashes=[]
105
148
  for input_ in all_inputs_:
106
- line_ = _input_line(input_, ns)
149
+ line_ = _input_line(input_, ns, initializers)
107
150
  code_txt.write(f"\n\t{line_}")
108
151
  for derived_ in all_derived_:
109
- line_ = _derived_line(derived_, ns, _make_args, jit_options)
152
+ line_ = _derived_line(derived_, ns, initializers, derive_hashes, _make_args, jit_options)
110
153
  code_txt.write(f"\n\t{line_}")
111
- hash_ = code_block_hash(code_txt.getvalue())
154
+ hash_str = f"code_block = {code_txt.getvalue()} initializers = {list(initializers.values())} derive_hashes = {derive_hashes}"
155
+ hash_ = code_block_hash(hash_str)
112
156
  code_txt.write(f"""\n\taccess_tuple = ({", ".join([n.name for n in access_nodes])})""")
113
157
  code_txt.write(f"\n\treturn access_tuple")
114
158
  code_txt = code_txt.getvalue()
115
- make_params = ", ".join(_make_args)
159
+ make_params = ", ".join(chain(_make_args, initializers.keys()))
116
160
  make_name = f"_make_{hash_}"
117
161
  code_txt = f"""
118
162
  @njit(**jit_options)
@@ -0,0 +1,35 @@
1
+ from inspect import getsource
2
+ from textwrap import indent
3
+
4
+ from numbox.core.work.builder import _derive_funcs
5
+ from numbox.core.work.work import Work
6
+
7
+
8
+ def get_func_code(derive_func_p_):
9
+ derive_func_ = _derive_funcs.get(derive_func_p_)
10
+ return derive_func_.__name__, indent(getsource(derive_func_), " ")
11
+
12
+
13
+ def _explain(work: Work, derivation_: list, derived_: set):
14
+ if work.name in derived_:
15
+ return
16
+ if len(work.sources) == 0:
17
+ derivation_.append(f"{work.name}: end node\n")
18
+ derived_.add(work.name)
19
+ return
20
+ inputs_names = []
21
+ for source in work.sources:
22
+ _explain(source, derivation_, derived_)
23
+ inputs_names.append(source.name)
24
+ derive_func_ptrs = work.derive
25
+ derive_func_name, derive_func_code = get_func_code(derive_func_ptrs[1])
26
+ derivation_.append(f"""{work.name}: {derive_func_name}({", ".join(inputs_names)})
27
+
28
+ {derive_func_code}""")
29
+ derived_.add(work.name)
30
+
31
+
32
+ def explain(work: Work):
33
+ derivation = []
34
+ _explain(work, derivation, set())
35
+ return "\n".join(derivation)
numbox/core/work/work.py CHANGED
@@ -17,7 +17,7 @@ from numbox.core.work.lowlevel_work_utils import ll_make_work, WorkTypeClass
17
17
  from numbox.core.work.node import NodeType
18
18
  from numbox.core.work.node_base import NodeBase, NodeBaseType
19
19
  from numbox.utils.lowlevel import (
20
- extract_struct_member, _cast, is_not_null, get_func_p_from_func_struct, get_ll_func_sig
20
+ extract_struct_member, _cast, _get_func_tuple, is_not_null, get_func_p_from_func_struct, get_ll_func_sig
21
21
  )
22
22
 
23
23
 
@@ -73,6 +73,11 @@ class Work(NodeBase):
73
73
  def sources(self):
74
74
  return self.sources
75
75
 
76
+ @property
77
+ @njit(**default_jit_options)
78
+ def derive(self):
79
+ return _get_func_tuple(self.derive)
80
+
76
81
  @property
77
82
  @njit(**default_jit_options)
78
83
  def derived(self):
@@ -441,9 +446,8 @@ def ol_depends_on(self_ty, obj_ty):
441
446
  node = self.as_node()
442
447
  return name_ in node.all_inputs_names()
443
448
  else:
444
- assert isinstance(obj_ty, WorkTypeClass), f"Cannot handle {obj_ty}"
445
-
446
449
  def _(self, obj_):
447
450
  node = self.as_node()
448
451
  return obj_.name in node.all_inputs_names()
452
+ assert isinstance(obj_ty, WorkTypeClass), f"Cannot handle {obj_ty}"
449
453
  return _
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: numbox
3
- Version: 0.2.3
3
+ Version: 0.2.5
4
4
  Author: Mikhail Goykhman
5
5
  License: MIT License (with Citation Clause)
6
6
 
@@ -1,4 +1,4 @@
1
- numbox/__init__.py,sha256=XtWUl6HPylv5jZLd2KkgtPptuzuda93kC2REmOrF-Cs,22
1
+ numbox/__init__.py,sha256=8f4ummWTPl6PtdE9DzSUgZhPjGioA_NDC-hDpqzB9qI,22
2
2
  numbox/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  numbox/core/configurations.py,sha256=0bCmxXL-QMwtvyIDhpXLeT-1KJMf_QpH0wLuEvYLGxQ,68
4
4
  numbox/core/any/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -15,14 +15,15 @@ numbox/core/bindings/utils.py,sha256=aRtN8oUYBk9vgoUGaUJosGx0Za-vvCNwwbZg_g_-LRs
15
15
  numbox/core/proxy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
16
  numbox/core/proxy/proxy.py,sha256=kGYlEdLK40lxxu56e_S32s9YuQ6AuQnFegt5uQrUw5w,3889
17
17
  numbox/core/work/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
- numbox/core/work/builder.py,sha256=QaklRb-IciVNPlk1WnQ3Hfc8tHbWbuAQqdrlp51XCcM,3991
18
+ numbox/core/work/builder.py,sha256=tfrizyZuBy21zsoILELzQIj-wtYAuPitDqtVg7V1atw,5362
19
19
  numbox/core/work/combine_utils.py,sha256=qTVGke_ydzaTQ7o29DFjZWZzKjRNKb0L3yJMaR3TLII,2430
20
+ numbox/core/work/explain.py,sha256=qEorYHRSe8P2MygodCYsz57UtWeRfaS27xHSw3hBgmo,1063
20
21
  numbox/core/work/loader_utils.py,sha256=g83mDWidZJ8oLWP3I3rK8aGISYOO2S-w6HDgtosCyck,1572
21
22
  numbox/core/work/lowlevel_work_utils.py,sha256=TgRRcNfks0oaOXGXXr3ptafd_Xv_lpmH8sjBrJ9bPuI,5748
22
23
  numbox/core/work/node.py,sha256=CMolyoRQjG2A-pTQqZQ0kxKOYTKipWRC0mu8RWHuTUI,5096
23
24
  numbox/core/work/node_base.py,sha256=uI7asM2itQcHuOByXyJtqvrd4ovW6EXDRdHYp3JVHQ0,998
24
25
  numbox/core/work/print_tree.py,sha256=y2u7xmbHvpcA57y8PrGSqOunLNCqhgNXdVtXHqvy1M0,2340
25
- numbox/core/work/work.py,sha256=oC71F2y-NkIF9Ox63trlv061nYBxla6R-F2Nj-7NXI4,14595
26
+ numbox/core/work/work.py,sha256=V_pYW0sqdYHh45ago3aMz0fG4U_UfsNLIcpBejn_ttU,14725
26
27
  numbox/core/work/work_utils.py,sha256=3q_nnBdzuxWWcdFpbRL2H0T9ZNkUgx1J1uhiZkX3YG4,1039
27
28
  numbox/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
29
  numbox/utils/highlevel.py,sha256=gXYzLsFPKHQfGqaz-Z4DWcCQddv0dS6SKwIsM-_xjYg,1487
@@ -30,8 +31,8 @@ numbox/utils/lowlevel.py,sha256=ACpf8_HyOIsobPlZ31bapkEyuCsV5dojW3AFrcKykrw,1071
30
31
  numbox/utils/meminfo.py,sha256=ykFi8Vt0WcHI3ztgMwvpn6NqaflDSQGL8tjI01jrzm0,1759
31
32
  numbox/utils/timer.py,sha256=KkAkWOHQ72WtPjyiAzt_tF1q0DcOnCDkITTb85DvkUM,553
32
33
  numbox/utils/void_type.py,sha256=IkZsjNeAIShYJtvWbvERdHnl_mbF1rCRWiM3gp6II8U,404
33
- numbox-0.2.3.dist-info/LICENSE,sha256=YYgNvjH_p6-1NsdrIqGJnr1GUbZzA_8DxsP6vVfM6nY,1446
34
- numbox-0.2.3.dist-info/METADATA,sha256=e7MF4nI2ntAqX8CGKWS1FvUiEswd2rtRW-rysf4WWJc,2792
35
- numbox-0.2.3.dist-info/WHEEL,sha256=iAkIy5fosb7FzIOwONchHf19Qu7_1wCWyFNR5gu9nU0,91
36
- numbox-0.2.3.dist-info/top_level.txt,sha256=A67jOkfqidCSYYm6ifjN_WZyIiR1B27fjxv6nNbPvjc,7
37
- numbox-0.2.3.dist-info/RECORD,,
34
+ numbox-0.2.5.dist-info/LICENSE,sha256=YYgNvjH_p6-1NsdrIqGJnr1GUbZzA_8DxsP6vVfM6nY,1446
35
+ numbox-0.2.5.dist-info/METADATA,sha256=kHcNZstr-whJ0XoJ6IcoXACjnAn33yjvJgdn4Ksx6sk,2792
36
+ numbox-0.2.5.dist-info/WHEEL,sha256=iAkIy5fosb7FzIOwONchHf19Qu7_1wCWyFNR5gu9nU0,91
37
+ numbox-0.2.5.dist-info/top_level.txt,sha256=A67jOkfqidCSYYm6ifjN_WZyIiR1B27fjxv6nNbPvjc,7
38
+ numbox-0.2.5.dist-info/RECORD,,
File without changes