mapFolding 0.4.2__py3-none-any.whl → 0.4.3__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.
- mapFolding/__init__.py +2 -1
- mapFolding/basecamp.py +1 -1
- mapFolding/beDRY.py +61 -39
- mapFolding/oeis.py +18 -17
- mapFolding/someAssemblyRequired/synthesizeNumba.py +40 -48
- mapFolding/someAssemblyRequired/synthesizeNumbaGeneralized.py +83 -12
- mapFolding/someAssemblyRequired/synthesizeNumbaJob.py +12 -23
- mapFolding/someAssemblyRequired/synthesizeNumbaModules.py +82 -30
- mapFolding/syntheticModules/numbaCount.py +158 -0
- mapFolding/syntheticModules/numba_doTheNeedful.py +5 -12
- mapFolding/theDao.py +75 -75
- mapFolding/theSSOT.py +50 -189
- mapFolding/theSSOTdatatypes.py +168 -0
- {mapFolding-0.4.2.dist-info → mapFolding-0.4.3.dist-info}/METADATA +1 -1
- mapFolding-0.4.3.dist-info/RECORD +40 -0
- tests/conftest.py +30 -1
- tests/test_computations.py +27 -63
- tests/test_oeis.py +7 -10
- mapFolding/syntheticModules/numba_countInitialize.py +0 -52
- mapFolding/syntheticModules/numba_countParallel.py +0 -65
- mapFolding/syntheticModules/numba_countSequential.py +0 -67
- mapFolding/theSSOTnumba.py +0 -125
- mapFolding-0.4.2.dist-info/RECORD +0 -42
- {mapFolding-0.4.2.dist-info → mapFolding-0.4.3.dist-info}/LICENSE +0 -0
- {mapFolding-0.4.2.dist-info → mapFolding-0.4.3.dist-info}/WHEEL +0 -0
- {mapFolding-0.4.2.dist-info → mapFolding-0.4.3.dist-info}/entry_points.txt +0 -0
- {mapFolding-0.4.2.dist-info → mapFolding-0.4.3.dist-info}/top_level.txt +0 -0
mapFolding/theDao.py
CHANGED
|
@@ -3,17 +3,17 @@ from numba import prange
|
|
|
3
3
|
from numpy import dtype, integer, ndarray
|
|
4
4
|
from typing import Any, Tuple
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
my[indexMy.
|
|
6
|
+
# `.value` is not necessary for this module or most modules. But, this module is transformed into Numba "jitted" functions, and Numba won't use `Enum` for an ndarray index without `.value`.
|
|
7
|
+
def activeLeafConnectedToItself(my: ndarray[Tuple[int], dtype[integer[Any]]]) -> Any:
|
|
8
|
+
return my[indexMy.leafConnectee.value] == my[indexMy.leaf1ndex.value]
|
|
9
9
|
|
|
10
|
-
def
|
|
11
|
-
return my[indexMy.leaf1ndex.value]
|
|
10
|
+
def activeLeafGreaterThan0(my: ndarray[Tuple[int], dtype[integer[Any]]]) -> Any:
|
|
11
|
+
return my[indexMy.leaf1ndex.value] > 0
|
|
12
12
|
|
|
13
|
-
def
|
|
13
|
+
def activeLeafGreaterThanLeavesTotal(foldGroups: ndarray[Tuple[int], dtype[integer[Any]]], my: ndarray[Tuple[int], dtype[integer[Any]]]) -> Any:
|
|
14
14
|
return my[indexMy.leaf1ndex.value] > foldGroups[-1]
|
|
15
15
|
|
|
16
|
-
def
|
|
16
|
+
def activeLeafIsTheFirstLeaf(my: ndarray[Tuple[int], dtype[integer[Any]]]) -> Any:
|
|
17
17
|
return my[indexMy.leaf1ndex.value] <= 1
|
|
18
18
|
|
|
19
19
|
def allDimensionsAreUnconstrained(my: ndarray[Tuple[int], dtype[integer[Any]]]) -> Any:
|
|
@@ -24,44 +24,47 @@ def backtrack(my: ndarray[Tuple[int], dtype[integer[Any]]], track: ndarray[Tuple
|
|
|
24
24
|
track[indexTrack.leafBelow.value, track[indexTrack.leafAbove.value, my[indexMy.leaf1ndex.value]]] = track[indexTrack.leafBelow.value, my[indexMy.leaf1ndex.value]]
|
|
25
25
|
track[indexTrack.leafAbove.value, track[indexTrack.leafBelow.value, my[indexMy.leaf1ndex.value]]] = track[indexTrack.leafAbove.value, my[indexMy.leaf1ndex.value]]
|
|
26
26
|
|
|
27
|
-
def backtrackCondition(my: ndarray[Tuple[int], dtype[integer[Any]]], track: ndarray[Tuple[int, int], dtype[integer[Any]]]) -> Any:
|
|
28
|
-
return my[indexMy.leaf1ndex.value] and my[indexMy.gap1ndex.value] == track[indexTrack.gapRangeStart.value, my[indexMy.leaf1ndex.value] - 1]
|
|
29
|
-
|
|
30
|
-
def gap1ndexCeilingIncrement(my: ndarray[Tuple[int], dtype[integer[Any]]]) -> None:
|
|
31
|
-
my[indexMy.gap1ndexCeiling.value] += 1
|
|
32
|
-
|
|
33
27
|
def countGaps(gapsWhere: ndarray[Tuple[int], dtype[integer[Any]]], my: ndarray[Tuple[int], dtype[integer[Any]]], track: ndarray[Tuple[int, int], dtype[integer[Any]]]) -> None:
|
|
34
28
|
gapsWhere[my[indexMy.gap1ndexCeiling.value]] = my[indexMy.leafConnectee.value]
|
|
35
29
|
if track[indexTrack.countDimensionsGapped.value, my[indexMy.leafConnectee.value]] == 0:
|
|
36
|
-
|
|
30
|
+
incrementGap1ndexCeiling(my=my)
|
|
37
31
|
track[indexTrack.countDimensionsGapped.value, my[indexMy.leafConnectee.value]] += 1
|
|
38
32
|
|
|
33
|
+
def decrementDimensionsUnconstrained(my: ndarray[Tuple[int], dtype[integer[Any]]]) -> None:
|
|
34
|
+
my[indexMy.dimensionsUnconstrained.value] -= 1
|
|
35
|
+
|
|
39
36
|
def dimensionsUnconstrainedCondition(connectionGraph: ndarray[Tuple[int, int, int], dtype[integer[Any]]], my: ndarray[Tuple[int], dtype[integer[Any]]]) -> Any:
|
|
40
37
|
return connectionGraph[my[indexMy.indexDimension.value], my[indexMy.leaf1ndex.value], my[indexMy.leaf1ndex.value]] == my[indexMy.leaf1ndex.value]
|
|
41
38
|
|
|
42
|
-
def dimensionsUnconstrainedDecrement(my: ndarray[Tuple[int], dtype[integer[Any]]]) -> None:
|
|
43
|
-
my[indexMy.dimensionsUnconstrained.value] -= 1
|
|
44
|
-
|
|
45
39
|
def filterCommonGaps(gapsWhere: ndarray[Tuple[int], dtype[integer[Any]]], my: ndarray[Tuple[int], dtype[integer[Any]]], track: ndarray[Tuple[int, int], dtype[integer[Any]]]) -> None:
|
|
46
40
|
gapsWhere[my[indexMy.gap1ndex.value]] = gapsWhere[my[indexMy.indexMiniGap.value]]
|
|
47
41
|
if track[indexTrack.countDimensionsGapped.value, gapsWhere[my[indexMy.indexMiniGap.value]]] == my[indexMy.dimensionsUnconstrained.value]:
|
|
48
|
-
|
|
42
|
+
incrementActiveGap(my=my)
|
|
49
43
|
track[indexTrack.countDimensionsGapped.value, gapsWhere[my[indexMy.indexMiniGap.value]]] = 0
|
|
50
44
|
|
|
51
|
-
def
|
|
52
|
-
my[indexMy.
|
|
53
|
-
my[indexMy.gap1ndexCeiling.value] = track[indexTrack.gapRangeStart.value, my[indexMy.leaf1ndex.value] - 1]
|
|
54
|
-
my[indexMy.indexDimension.value] = 0
|
|
45
|
+
def incrementActiveGap(my: ndarray[Tuple[int], dtype[integer[Any]]]) -> None:
|
|
46
|
+
my[indexMy.gap1ndex.value] += 1
|
|
55
47
|
|
|
56
|
-
def
|
|
48
|
+
def incrementGap1ndexCeiling(my: ndarray[Tuple[int], dtype[integer[Any]]]) -> None:
|
|
49
|
+
my[indexMy.gap1ndexCeiling.value] += 1
|
|
50
|
+
|
|
51
|
+
def incrementIndexDimension(my: ndarray[Tuple[int], dtype[integer[Any]]]) -> None:
|
|
57
52
|
my[indexMy.indexDimension.value] += 1
|
|
58
53
|
|
|
59
|
-
def
|
|
54
|
+
def incrementIndexMiniGap(my: ndarray[Tuple[int], dtype[integer[Any]]]) -> None:
|
|
60
55
|
my[indexMy.indexMiniGap.value] += 1
|
|
61
56
|
|
|
62
|
-
def
|
|
57
|
+
def initializeIndexMiniGap(my: ndarray[Tuple[int], dtype[integer[Any]]]) -> None:
|
|
63
58
|
my[indexMy.indexMiniGap.value] = my[indexMy.gap1ndex.value]
|
|
64
59
|
|
|
60
|
+
def initializeLeafConnectee(connectionGraph: ndarray[Tuple[int, int, int], dtype[integer[Any]]], my: ndarray[Tuple[int], dtype[integer[Any]]]) -> None:
|
|
61
|
+
my[indexMy.leafConnectee.value] = connectionGraph[my[indexMy.indexDimension.value], my[indexMy.leaf1ndex.value], my[indexMy.leaf1ndex.value]]
|
|
62
|
+
|
|
63
|
+
def initializeVariablesToFindGaps(my: ndarray[Tuple[int], dtype[integer[Any]]], track: ndarray[Tuple[int, int], dtype[integer[Any]]]) -> None:
|
|
64
|
+
my[indexMy.dimensionsUnconstrained.value] = my[indexMy.dimensionsTotal.value]
|
|
65
|
+
my[indexMy.gap1ndexCeiling.value] = track[indexTrack.gapRangeStart.value, my[indexMy.leaf1ndex.value] - 1]
|
|
66
|
+
my[indexMy.indexDimension.value] = 0
|
|
67
|
+
|
|
65
68
|
def insertUnconstrainedLeaf(gapsWhere: ndarray[Tuple[int], dtype[integer[Any]]], my: ndarray[Tuple[int], dtype[integer[Any]]]) -> None:
|
|
66
69
|
my[indexMy.indexLeaf.value] = 0
|
|
67
70
|
while my[indexMy.indexLeaf.value] < my[indexMy.leaf1ndex.value]:
|
|
@@ -69,26 +72,20 @@ def insertUnconstrainedLeaf(gapsWhere: ndarray[Tuple[int], dtype[integer[Any]]],
|
|
|
69
72
|
my[indexMy.gap1ndexCeiling.value] += 1
|
|
70
73
|
my[indexMy.indexLeaf.value] += 1
|
|
71
74
|
|
|
72
|
-
def
|
|
75
|
+
def leafBelowSentinelIs1(track: ndarray[Tuple[int, int], dtype[integer[Any]]]) -> Any:
|
|
73
76
|
return track[indexTrack.leafBelow.value, 0] == 1
|
|
74
77
|
|
|
75
|
-
def leafConnecteeInitialization(connectionGraph: ndarray[Tuple[int, int, int], dtype[integer[Any]]], my: ndarray[Tuple[int], dtype[integer[Any]]]) -> None:
|
|
76
|
-
my[indexMy.leafConnectee.value] = connectionGraph[my[indexMy.indexDimension.value], my[indexMy.leaf1ndex.value], my[indexMy.leaf1ndex.value]]
|
|
77
|
-
|
|
78
|
-
def leafConnecteeUpdate(connectionGraph: ndarray[Tuple[int, int, int], dtype[integer[Any]]], my: ndarray[Tuple[int], dtype[integer[Any]]], track: ndarray[Tuple[int, int], dtype[integer[Any]]]) -> None:
|
|
79
|
-
my[indexMy.leafConnectee.value] = connectionGraph[my[indexMy.indexDimension.value], my[indexMy.leaf1ndex.value], track[indexTrack.leafBelow.value, my[indexMy.leafConnectee.value]]]
|
|
80
|
-
|
|
81
|
-
def activeLeafConnectedToItself(my: ndarray[Tuple[int], dtype[integer[Any]]]) -> Any:
|
|
82
|
-
return my[indexMy.leafConnectee.value] == my[indexMy.leaf1ndex.value]
|
|
83
|
-
|
|
84
78
|
def loopingLeavesConnectedToActiveLeaf(my: ndarray[Tuple[int], dtype[integer[Any]]]) -> Any:
|
|
85
79
|
return my[indexMy.leafConnectee.value] != my[indexMy.leaf1ndex.value]
|
|
86
80
|
|
|
81
|
+
def loopingToActiveGapCeiling(my: ndarray[Tuple[int], dtype[integer[Any]]]) -> Any:
|
|
82
|
+
return my[indexMy.indexMiniGap.value] < my[indexMy.gap1ndexCeiling.value]
|
|
83
|
+
|
|
87
84
|
def loopUpToDimensionsTotal(my: ndarray[Tuple[int], dtype[integer[Any]]]) -> Any:
|
|
88
85
|
return my[indexMy.indexDimension.value] < my[indexMy.dimensionsTotal.value]
|
|
89
86
|
|
|
90
|
-
def
|
|
91
|
-
return my[indexMy.
|
|
87
|
+
def noGapsHere(my: ndarray[Tuple[int], dtype[integer[Any]]], track: ndarray[Tuple[int, int], dtype[integer[Any]]]) -> Any:
|
|
88
|
+
return my[indexMy.leaf1ndex.value] > 0 and my[indexMy.gap1ndex.value] == track[indexTrack.gapRangeStart.value, my[indexMy.leaf1ndex.value] - 1]
|
|
92
89
|
|
|
93
90
|
def placeLeaf(gapsWhere: ndarray[Tuple[int], dtype[integer[Any]]], my: ndarray[Tuple[int], dtype[integer[Any]]], track: ndarray[Tuple[int, int], dtype[integer[Any]]]) -> None:
|
|
94
91
|
my[indexMy.gap1ndex.value] -= 1
|
|
@@ -99,37 +96,40 @@ def placeLeaf(gapsWhere: ndarray[Tuple[int], dtype[integer[Any]]], my: ndarray[T
|
|
|
99
96
|
track[indexTrack.gapRangeStart.value, my[indexMy.leaf1ndex.value]] = my[indexMy.gap1ndex.value]
|
|
100
97
|
my[indexMy.leaf1ndex.value] += 1
|
|
101
98
|
|
|
102
|
-
def
|
|
103
|
-
return my[indexMy.leaf1ndex.value]
|
|
99
|
+
def thereIsAnActiveLeaf(my: ndarray[Tuple[int], dtype[integer[Any]]]) -> Any:
|
|
100
|
+
return my[indexMy.leaf1ndex.value] > 0
|
|
104
101
|
|
|
105
|
-
def
|
|
102
|
+
def thisIsMyTaskIndex(my: ndarray[Tuple[int], dtype[integer[Any]]]) -> Any:
|
|
106
103
|
return my[indexMy.leaf1ndex.value] != my[indexMy.taskDivisions.value] or my[indexMy.leafConnectee.value] % my[indexMy.taskDivisions.value] == my[indexMy.taskIndex.value]
|
|
107
104
|
|
|
105
|
+
def updateLeafConnectee(connectionGraph: ndarray[Tuple[int, int, int], dtype[integer[Any]]], my: ndarray[Tuple[int], dtype[integer[Any]]], track: ndarray[Tuple[int, int], dtype[integer[Any]]]) -> None:
|
|
106
|
+
my[indexMy.leafConnectee.value] = connectionGraph[my[indexMy.indexDimension.value], my[indexMy.leaf1ndex.value], track[indexTrack.leafBelow.value, my[indexMy.leafConnectee.value]]]
|
|
107
|
+
|
|
108
108
|
def countInitialize(connectionGraph: ndarray[Tuple[int, int, int], dtype[integer[Any]]]
|
|
109
109
|
, gapsWhere: ndarray[Tuple[int] , dtype[integer[Any]]]
|
|
110
110
|
, my: ndarray[Tuple[int] , dtype[integer[Any]]]
|
|
111
111
|
, track: ndarray[Tuple[int, int] , dtype[integer[Any]]]
|
|
112
112
|
) -> None:
|
|
113
113
|
|
|
114
|
-
while
|
|
115
|
-
if
|
|
116
|
-
|
|
114
|
+
while activeLeafGreaterThan0(my=my):
|
|
115
|
+
if activeLeafIsTheFirstLeaf(my=my) or leafBelowSentinelIs1(track=track):
|
|
116
|
+
initializeVariablesToFindGaps(my=my, track=track)
|
|
117
117
|
while loopUpToDimensionsTotal(my=my):
|
|
118
118
|
if dimensionsUnconstrainedCondition(connectionGraph=connectionGraph, my=my):
|
|
119
|
-
|
|
119
|
+
decrementDimensionsUnconstrained(my=my)
|
|
120
120
|
else:
|
|
121
|
-
|
|
121
|
+
initializeLeafConnectee(connectionGraph=connectionGraph, my=my)
|
|
122
122
|
while loopingLeavesConnectedToActiveLeaf(my=my):
|
|
123
123
|
countGaps(gapsWhere=gapsWhere, my=my, track=track)
|
|
124
|
-
|
|
125
|
-
|
|
124
|
+
updateLeafConnectee(connectionGraph=connectionGraph, my=my, track=track)
|
|
125
|
+
incrementIndexDimension(my=my)
|
|
126
126
|
if allDimensionsAreUnconstrained(my=my):
|
|
127
127
|
insertUnconstrainedLeaf(gapsWhere=gapsWhere, my=my)
|
|
128
|
-
|
|
128
|
+
initializeIndexMiniGap(my=my)
|
|
129
129
|
while loopingToActiveGapCeiling(my=my):
|
|
130
130
|
filterCommonGaps(gapsWhere=gapsWhere, my=my, track=track)
|
|
131
|
-
|
|
132
|
-
if
|
|
131
|
+
incrementIndexMiniGap(my=my)
|
|
132
|
+
if thereIsAnActiveLeaf(my=my):
|
|
133
133
|
placeLeaf(gapsWhere=gapsWhere, my=my, track=track)
|
|
134
134
|
if my[indexMy.gap1ndex.value] > 0:
|
|
135
135
|
return
|
|
@@ -156,29 +156,29 @@ def countParallel(connectionGraph: ndarray[Tuple[int, int, int], dtype[integer[A
|
|
|
156
156
|
|
|
157
157
|
my[indexMy.taskIndex.value] = indexSherpa
|
|
158
158
|
|
|
159
|
-
while
|
|
160
|
-
if
|
|
161
|
-
if
|
|
159
|
+
while activeLeafGreaterThan0(my=my):
|
|
160
|
+
if activeLeafIsTheFirstLeaf(my=my) or leafBelowSentinelIs1(track=track):
|
|
161
|
+
if activeLeafGreaterThanLeavesTotal(foldGroups=foldGroups, my=my):
|
|
162
162
|
groupsOfFolds += 1
|
|
163
163
|
else:
|
|
164
|
-
|
|
164
|
+
initializeVariablesToFindGaps(my=my, track=track)
|
|
165
165
|
while loopUpToDimensionsTotal(my=my):
|
|
166
166
|
if dimensionsUnconstrainedCondition(connectionGraph=connectionGraph, my=my):
|
|
167
|
-
|
|
167
|
+
decrementDimensionsUnconstrained(my=my)
|
|
168
168
|
else:
|
|
169
|
-
|
|
169
|
+
initializeLeafConnectee(connectionGraph=connectionGraph, my=my)
|
|
170
170
|
while loopingLeavesConnectedToActiveLeaf(my=my):
|
|
171
|
-
if
|
|
171
|
+
if thisIsMyTaskIndex(my=my):
|
|
172
172
|
countGaps(gapsWhere=gapsWhere, my=my, track=track)
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
173
|
+
updateLeafConnectee(connectionGraph=connectionGraph, my=my, track=track)
|
|
174
|
+
incrementIndexDimension(my=my)
|
|
175
|
+
initializeIndexMiniGap(my=my)
|
|
176
176
|
while loopingToActiveGapCeiling(my=my):
|
|
177
177
|
filterCommonGaps(gapsWhere=gapsWhere, my=my, track=track)
|
|
178
|
-
|
|
179
|
-
while
|
|
178
|
+
incrementIndexMiniGap(my=my)
|
|
179
|
+
while noGapsHere(my=my, track=track):
|
|
180
180
|
backtrack(my=my, track=track)
|
|
181
|
-
if
|
|
181
|
+
if thereIsAnActiveLeaf(my=my):
|
|
182
182
|
placeLeaf(gapsWhere=gapsWhere, my=my, track=track)
|
|
183
183
|
foldGroups[my[indexMy.taskIndex.value]] = groupsOfFolds
|
|
184
184
|
|
|
@@ -191,28 +191,28 @@ def countSequential( connectionGraph: ndarray[Tuple[int, int, int], dtype[intege
|
|
|
191
191
|
|
|
192
192
|
groupsOfFolds: int = 0
|
|
193
193
|
|
|
194
|
-
while
|
|
195
|
-
if
|
|
196
|
-
if
|
|
194
|
+
while activeLeafGreaterThan0(my=my):
|
|
195
|
+
if activeLeafIsTheFirstLeaf(my=my) or leafBelowSentinelIs1(track=track):
|
|
196
|
+
if activeLeafGreaterThanLeavesTotal(foldGroups=foldGroups, my=my):
|
|
197
197
|
groupsOfFolds += 1
|
|
198
198
|
else:
|
|
199
|
-
|
|
199
|
+
initializeVariablesToFindGaps(my=my, track=track)
|
|
200
200
|
while loopUpToDimensionsTotal(my=my):
|
|
201
|
-
|
|
201
|
+
initializeLeafConnectee(connectionGraph=connectionGraph, my=my)
|
|
202
202
|
if activeLeafConnectedToItself(my=my):
|
|
203
|
-
|
|
203
|
+
decrementDimensionsUnconstrained(my=my)
|
|
204
204
|
else:
|
|
205
205
|
while loopingLeavesConnectedToActiveLeaf(my=my):
|
|
206
206
|
countGaps(gapsWhere=gapsWhere, my=my, track=track)
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
207
|
+
updateLeafConnectee(connectionGraph=connectionGraph, my=my, track=track)
|
|
208
|
+
incrementIndexDimension(my=my)
|
|
209
|
+
initializeIndexMiniGap(my=my)
|
|
210
210
|
while loopingToActiveGapCeiling(my=my):
|
|
211
211
|
filterCommonGaps(gapsWhere=gapsWhere, my=my, track=track)
|
|
212
|
-
|
|
213
|
-
while
|
|
212
|
+
incrementIndexMiniGap(my=my)
|
|
213
|
+
while noGapsHere(my=my, track=track):
|
|
214
214
|
backtrack(my=my, track=track)
|
|
215
|
-
if
|
|
215
|
+
if thereIsAnActiveLeaf(my=my):
|
|
216
216
|
placeLeaf(gapsWhere=gapsWhere, my=my, track=track)
|
|
217
217
|
foldGroups[my[indexMy.taskIndex.value]] = groupsOfFolds
|
|
218
218
|
|
mapFolding/theSSOT.py
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
from
|
|
2
|
-
from
|
|
1
|
+
from mapFolding.theSSOTdatatypes import *
|
|
2
|
+
from numba.core.compiler import CompilerBase as numbaCompilerBase
|
|
3
3
|
from numpy import dtype, integer, ndarray
|
|
4
4
|
from types import ModuleType
|
|
5
|
-
from typing import Any, Callable,
|
|
6
|
-
import enum
|
|
7
|
-
import numba
|
|
8
|
-
import numpy
|
|
9
|
-
import numpy.typing
|
|
5
|
+
from typing import Any, Callable, Dict, Final, Tuple, TYPE_CHECKING, Union, cast
|
|
10
6
|
import pathlib
|
|
11
7
|
import sys
|
|
12
8
|
|
|
@@ -20,45 +16,22 @@ if TYPE_CHECKING:
|
|
|
20
16
|
else:
|
|
21
17
|
TypedDict = dict
|
|
22
18
|
|
|
23
|
-
"""I have hobbled together:
|
|
24
|
-
TypedDict, Enum, defaultdict, and lookup dictionaries to make DIY immutability and delayed realization/instantiation.
|
|
25
|
-
Nevertheless, I am both confident that all of these processes will be replaced and completely ignorant of what will replace them."""
|
|
26
|
-
|
|
27
19
|
"""Technical concepts I am likely using and likely want to use more effectively:
|
|
28
20
|
- Configuration Registry
|
|
29
21
|
- Write-Once, Read-Many (WORM) / Immutable Initialization
|
|
30
22
|
- Lazy Initialization
|
|
31
|
-
- Separation of
|
|
32
|
-
|
|
33
|
-
Furthermore, I want to more clearly divorce the concept of a single _source_ of (a) truth from
|
|
34
|
-
the _authority_ of that truth. The analogy to a registry of ownership is still apt: the registry
|
|
35
|
-
is, at most, a single (or centralized) source of truth, but it is merely the place to register/record
|
|
36
|
-
the truth determined by some other authority.
|
|
23
|
+
- Separation of configuration from business logic
|
|
37
24
|
|
|
38
|
-
|
|
39
|
-
|
|
25
|
+
delay realization/instantiation until a concrete value is desired
|
|
26
|
+
moment of truth: when the value is needed, not when the value is defined
|
|
40
27
|
"""
|
|
41
28
|
|
|
42
|
-
"delay realization/instantiation until a concrete value is desired"
|
|
43
|
-
|
|
44
|
-
"moment of truth: when the value is needed, not when the value is defined"
|
|
45
|
-
|
|
46
|
-
"""What is a (not too complicated, integer) datatype?
|
|
47
|
-
- ecosystem/module
|
|
48
|
-
- must apathy|value|list of values
|
|
49
|
-
- mustn't apathy|value|list of values
|
|
50
|
-
- bit width
|
|
51
|
-
- bits maximum apathy|value
|
|
52
|
-
- bits minimum apathy|value
|
|
53
|
-
- magnitude maximum apathy|value
|
|
54
|
-
- ?magnitude minimum apathy|value
|
|
55
|
-
- signedness apathy|non-negative|non-positive|both
|
|
56
|
-
"""
|
|
57
|
-
|
|
58
29
|
myPackageNameIs = "mapFolding"
|
|
59
30
|
|
|
60
31
|
moduleOfSyntheticModules = "syntheticModules"
|
|
61
|
-
|
|
32
|
+
# TODO I'm not sure if this is the right tool for the job.
|
|
33
|
+
formatFilenameModuleDEFAULT = "numba_{callableTarget}.py"
|
|
34
|
+
dispatcherCallableNameDEFAULT = "doTheNeedful"
|
|
62
35
|
|
|
63
36
|
def getPathPackage() -> pathlib.Path:
|
|
64
37
|
import importlib, inspect
|
|
@@ -99,159 +72,6 @@ class computationState(TypedDict):
|
|
|
99
72
|
my: ndarray[Tuple[int] , dtype[integer[Any]]]
|
|
100
73
|
track: ndarray[Tuple[int, int] , dtype[integer[Any]]]
|
|
101
74
|
|
|
102
|
-
@enum.verify(enum.CONTINUOUS, enum.UNIQUE) if sys.version_info >= (3, 11) else lambda x: x
|
|
103
|
-
class EnumIndices(enum.IntEnum):
|
|
104
|
-
"""Base class for index enums."""
|
|
105
|
-
@staticmethod
|
|
106
|
-
def _generate_next_value_(name: str, start: int, count: int, last_values: list[Any]) -> int:
|
|
107
|
-
"""0-indexed."""
|
|
108
|
-
return count
|
|
109
|
-
|
|
110
|
-
def __index__(self) -> int:
|
|
111
|
-
"""Adapt enum to the ultra-rare event of indexing a NumPy 'ndarray', which is not the
|
|
112
|
-
same as `array.array`. See NumPy.org; I think it will be very popular someday."""
|
|
113
|
-
return self.value
|
|
114
|
-
|
|
115
|
-
class indexMy(EnumIndices):
|
|
116
|
-
"""Indices for scalar values."""
|
|
117
|
-
dimensionsTotal = enum.auto()
|
|
118
|
-
dimensionsUnconstrained = enum.auto()
|
|
119
|
-
gap1ndex = enum.auto()
|
|
120
|
-
gap1ndexCeiling = enum.auto()
|
|
121
|
-
indexDimension = enum.auto()
|
|
122
|
-
indexLeaf = enum.auto()
|
|
123
|
-
indexMiniGap = enum.auto()
|
|
124
|
-
leaf1ndex = enum.auto()
|
|
125
|
-
leafConnectee = enum.auto()
|
|
126
|
-
taskDivisions = enum.auto()
|
|
127
|
-
taskIndex = enum.auto()
|
|
128
|
-
|
|
129
|
-
class indexTrack(EnumIndices):
|
|
130
|
-
"""Indices for state tracking array."""
|
|
131
|
-
leafAbove = enum.auto()
|
|
132
|
-
leafBelow = enum.auto()
|
|
133
|
-
countDimensionsGapped = enum.auto()
|
|
134
|
-
gapRangeStart = enum.auto()
|
|
135
|
-
|
|
136
|
-
_datatypeDefault: Final[Dict[str, str]] = {
|
|
137
|
-
'elephino': 'uint8',
|
|
138
|
-
'foldsTotal': 'int64',
|
|
139
|
-
'leavesTotal': 'uint8',
|
|
140
|
-
}
|
|
141
|
-
_datatypeModule = ''
|
|
142
|
-
_datatypeModuleDEFAULT: Final[str] = 'numpy'
|
|
143
|
-
|
|
144
|
-
_datatype: Dict[str, str] = defaultdict(str)
|
|
145
|
-
|
|
146
|
-
def reportDatatypeLimit(identifier: str, datatype: str, sourGrapes: Optional[bool] = False) -> str:
|
|
147
|
-
global _datatype
|
|
148
|
-
if not _datatype[identifier]:
|
|
149
|
-
_datatype[identifier] = datatype
|
|
150
|
-
elif _datatype[identifier] == datatype:
|
|
151
|
-
pass
|
|
152
|
-
elif sourGrapes:
|
|
153
|
-
raise Exception(f"Datatype is '{_datatype[identifier]}' not '{datatype}', so you can take your ball and go home.")
|
|
154
|
-
return _datatype[identifier]
|
|
155
|
-
|
|
156
|
-
def setDatatypeModule(datatypeModule: str, sourGrapes: Optional[bool] = False) -> str:
|
|
157
|
-
global _datatypeModule
|
|
158
|
-
if not _datatypeModule:
|
|
159
|
-
_datatypeModule = datatypeModule
|
|
160
|
-
elif _datatypeModule == datatypeModule:
|
|
161
|
-
pass
|
|
162
|
-
elif sourGrapes:
|
|
163
|
-
raise Exception(f"Datatype module is '{_datatypeModule}' not '{datatypeModule}', so you can take your ball and go home.")
|
|
164
|
-
return _datatypeModule
|
|
165
|
-
|
|
166
|
-
def setDatatypeElephino(datatype: str, sourGrapes: Optional[bool] = False) -> str:
|
|
167
|
-
return reportDatatypeLimit('elephino', datatype, sourGrapes)
|
|
168
|
-
|
|
169
|
-
def setDatatypeFoldsTotal(datatype: str, sourGrapes: Optional[bool] = False) -> str:
|
|
170
|
-
return reportDatatypeLimit('foldsTotal', datatype, sourGrapes)
|
|
171
|
-
|
|
172
|
-
def setDatatypeLeavesTotal(datatype: str, sourGrapes: Optional[bool] = False) -> str:
|
|
173
|
-
return reportDatatypeLimit('leavesTotal', datatype, sourGrapes)
|
|
174
|
-
|
|
175
|
-
def _get_datatype(identifier: str) -> str:
|
|
176
|
-
global _datatype
|
|
177
|
-
if not _datatype[identifier]:
|
|
178
|
-
if identifier in indexMy._member_names_:
|
|
179
|
-
_datatype[identifier] = _datatypeDefault.get(identifier) or _get_datatype('elephino')
|
|
180
|
-
elif identifier in indexTrack._member_names_:
|
|
181
|
-
_datatype[identifier] = _datatypeDefault.get(identifier) or _get_datatype('elephino')
|
|
182
|
-
else:
|
|
183
|
-
_datatype[identifier] = _datatypeDefault.get(identifier) or _get_datatype('foldsTotal')
|
|
184
|
-
return _datatype[identifier]
|
|
185
|
-
|
|
186
|
-
def _getDatatypeModule() -> str:
|
|
187
|
-
global _datatypeModule
|
|
188
|
-
if not _datatypeModule:
|
|
189
|
-
_datatypeModule = _datatypeModuleDEFAULT
|
|
190
|
-
return _datatypeModule
|
|
191
|
-
|
|
192
|
-
def setInStone(identifier: str) -> Type[Any]:
|
|
193
|
-
datatypeModule = _getDatatypeModule()
|
|
194
|
-
datatypeStr = _get_datatype(identifier)
|
|
195
|
-
return cast(Type[Any], getattr(eval(datatypeModule), datatypeStr))
|
|
196
|
-
|
|
197
|
-
def hackSSOTdtype(identifier: str) -> Type[Any]:
|
|
198
|
-
_hackSSOTdtype={
|
|
199
|
-
'connectionGraph': 'dtypeLeavesTotal',
|
|
200
|
-
'dtypeElephino': 'dtypeElephino',
|
|
201
|
-
'dtypeFoldsTotal': 'dtypeFoldsTotal',
|
|
202
|
-
'dtypeLeavesTotal': 'dtypeLeavesTotal',
|
|
203
|
-
'foldGroups': 'dtypeFoldsTotal',
|
|
204
|
-
'gapsWhere': 'dtypeLeavesTotal',
|
|
205
|
-
'mapShape': 'dtypeLeavesTotal',
|
|
206
|
-
'my': 'dtypeElephino',
|
|
207
|
-
'track': 'dtypeElephino',
|
|
208
|
-
}
|
|
209
|
-
RubeGoldBerg = _hackSSOTdtype[identifier]
|
|
210
|
-
if RubeGoldBerg == 'dtypeElephino':
|
|
211
|
-
return setInStone('elephino')
|
|
212
|
-
elif RubeGoldBerg == 'dtypeFoldsTotal':
|
|
213
|
-
return setInStone('foldsTotal')
|
|
214
|
-
elif RubeGoldBerg == 'dtypeLeavesTotal':
|
|
215
|
-
return setInStone('leavesTotal')
|
|
216
|
-
raise Exception("Dude, you forgot to set a value in `hackSSOTdtype`.")
|
|
217
|
-
|
|
218
|
-
def hackSSOTdatatype(identifier: str) -> str:
|
|
219
|
-
_hackSSOTdatatype={
|
|
220
|
-
'connectionGraph': 'datatypeLeavesTotal',
|
|
221
|
-
'countDimensionsGapped': 'datatypeLeavesTotal',
|
|
222
|
-
'datatypeElephino': 'datatypeElephino',
|
|
223
|
-
'datatypeFoldsTotal': 'datatypeFoldsTotal',
|
|
224
|
-
'datatypeLeavesTotal': 'datatypeLeavesTotal',
|
|
225
|
-
'dimensionsTotal': 'datatypeLeavesTotal',
|
|
226
|
-
'dimensionsUnconstrained': 'datatypeLeavesTotal',
|
|
227
|
-
'foldGroups': 'datatypeFoldsTotal',
|
|
228
|
-
'gap1ndex': 'datatypeLeavesTotal',
|
|
229
|
-
'gap1ndexCeiling': 'datatypeElephino',
|
|
230
|
-
'gapRangeStart': 'datatypeElephino',
|
|
231
|
-
'gapsWhere': 'datatypeLeavesTotal',
|
|
232
|
-
'groupsOfFolds': 'datatypeFoldsTotal',
|
|
233
|
-
'indexDimension': 'datatypeLeavesTotal',
|
|
234
|
-
'indexLeaf': 'datatypeLeavesTotal',
|
|
235
|
-
'indexMiniGap': 'datatypeElephino',
|
|
236
|
-
'leaf1ndex': 'datatypeLeavesTotal',
|
|
237
|
-
'leafAbove': 'datatypeLeavesTotal',
|
|
238
|
-
'leafBelow': 'datatypeLeavesTotal',
|
|
239
|
-
'leafConnectee': 'datatypeLeavesTotal',
|
|
240
|
-
'mapShape': 'datatypeLeavesTotal',
|
|
241
|
-
'my': 'datatypeElephino',
|
|
242
|
-
'taskDivisions': 'datatypeLeavesTotal',
|
|
243
|
-
'taskIndex': 'datatypeLeavesTotal',
|
|
244
|
-
'track': 'datatypeElephino',
|
|
245
|
-
}
|
|
246
|
-
RubeGoldBerg = _hackSSOTdatatype[identifier]
|
|
247
|
-
if RubeGoldBerg == 'datatypeElephino':
|
|
248
|
-
return _get_datatype('elephino')
|
|
249
|
-
elif RubeGoldBerg == 'datatypeFoldsTotal':
|
|
250
|
-
return _get_datatype('foldsTotal')
|
|
251
|
-
elif RubeGoldBerg == 'datatypeLeavesTotal':
|
|
252
|
-
return _get_datatype('leavesTotal')
|
|
253
|
-
raise Exception("Dude, you forgot to set a value in `hackSSOTdatatype`.")
|
|
254
|
-
|
|
255
75
|
_datatypeModuleScalar = 'numba'
|
|
256
76
|
_decoratorCallable = 'jit'
|
|
257
77
|
def Z0Z_getDatatypeModuleScalar() -> str:
|
|
@@ -277,3 +97,44 @@ class FREAKOUT(Exception):
|
|
|
277
97
|
# TODO Learn how to assign theDao.py the power to set this truth
|
|
278
98
|
# while using theSSOT.py as the SSOT.
|
|
279
99
|
Z0Z_identifierCountFolds = 'groupsOfFolds'
|
|
100
|
+
|
|
101
|
+
class ParametersNumba(TypedDict):
|
|
102
|
+
_dbg_extend_lifetimes: NotRequired[bool]
|
|
103
|
+
_dbg_optnone: NotRequired[bool]
|
|
104
|
+
_nrt: NotRequired[bool]
|
|
105
|
+
boundscheck: NotRequired[bool]
|
|
106
|
+
cache: bool
|
|
107
|
+
debug: NotRequired[bool]
|
|
108
|
+
error_model: str
|
|
109
|
+
fastmath: bool
|
|
110
|
+
forceinline: bool
|
|
111
|
+
forceobj: NotRequired[bool]
|
|
112
|
+
inline: str
|
|
113
|
+
locals: NotRequired[Dict[str, Any]]
|
|
114
|
+
looplift: bool
|
|
115
|
+
no_cfunc_wrapper: bool
|
|
116
|
+
no_cpython_wrapper: bool
|
|
117
|
+
no_rewrites: NotRequired[bool]
|
|
118
|
+
nogil: NotRequired[bool]
|
|
119
|
+
nopython: bool
|
|
120
|
+
parallel: bool
|
|
121
|
+
pipeline_class: NotRequired[Type[numbaCompilerBase]]
|
|
122
|
+
signature_or_function: NotRequired[Union[Any, Callable, str, Tuple]]
|
|
123
|
+
target: NotRequired[str]
|
|
124
|
+
|
|
125
|
+
parametersNumbaFailEarly: Final[ParametersNumba] = { '_nrt': True, 'boundscheck': True, 'cache': True, 'error_model': 'python', 'fastmath': False, 'forceinline': True, 'inline': 'always', 'looplift': False, 'no_cfunc_wrapper': False, 'no_cpython_wrapper': False, 'nopython': True, 'parallel': False, }
|
|
126
|
+
"""For a production function: speed is irrelevant, error discovery is paramount, must be compatible with anything downstream."""
|
|
127
|
+
|
|
128
|
+
parametersNumbaDEFAULT: Final[ParametersNumba] = { '_nrt': True, 'boundscheck': False, 'cache': True, 'error_model': 'numpy', 'fastmath': True, 'forceinline': True, 'inline': 'always', 'looplift': False, 'no_cfunc_wrapper': False, 'no_cpython_wrapper': False, 'nopython': True, 'parallel': False, }
|
|
129
|
+
"""Middle of the road: fast, lean, but will talk to non-jitted functions."""
|
|
130
|
+
|
|
131
|
+
parametersNumbaParallelDEFAULT: Final[ParametersNumba] = { **parametersNumbaDEFAULT, '_nrt': True, 'parallel': True, }
|
|
132
|
+
"""Middle of the road: fast, lean, but will talk to non-jitted functions."""
|
|
133
|
+
|
|
134
|
+
parametersNumbaSuperJit: Final[ParametersNumba] = { **parametersNumbaDEFAULT, 'no_cfunc_wrapper': True, 'no_cpython_wrapper': True, }
|
|
135
|
+
"""Speed, no helmet, no talking to non-jitted functions."""
|
|
136
|
+
|
|
137
|
+
parametersNumbaSuperJitParallel: Final[ParametersNumba] = { **parametersNumbaSuperJit, '_nrt': True, 'parallel': True, }
|
|
138
|
+
"""Speed, no helmet, concurrency, no talking to non-jitted functions."""
|
|
139
|
+
|
|
140
|
+
parametersNumbaMinimum: Final[ParametersNumba] = { '_nrt': True, 'boundscheck': True, 'cache': True, 'error_model': 'numpy', 'fastmath': True, 'forceinline': False, 'inline': 'always', 'looplift': False, 'no_cfunc_wrapper': False, 'no_cpython_wrapper': False, 'nopython': False, 'forceobj': True, 'parallel': False, }
|