mapFolding 0.3.9__py3-none-any.whl → 0.3.10__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 +27 -9
- mapFolding/basecamp.py +1 -1
- mapFolding/beDRY.py +25 -13
- mapFolding/oeis.py +81 -71
- mapFolding/someAssemblyRequired/__init__.py +1 -0
- mapFolding/someAssemblyRequired/makeJob.py +1 -2
- mapFolding/someAssemblyRequired/synthesizeJobNumba.py +383 -0
- mapFolding/someAssemblyRequired/synthesizeModuleJAX.py +2 -2
- mapFolding/someAssemblyRequired/synthesizeModulesNumba.py +71 -44
- mapFolding/syntheticModules/numba_countInitialize.py +4 -5
- mapFolding/syntheticModules/numba_countParallel.py +5 -6
- mapFolding/syntheticModules/numba_countSequential.py +3 -4
- mapFolding/syntheticModules/numba_doTheNeedful.py +16 -19
- mapFolding/theDao.py +43 -44
- mapFolding/theSSOT.py +13 -31
- mapFolding/theSSOTnumba.py +115 -0
- {mapFolding-0.3.9.dist-info → mapFolding-0.3.10.dist-info}/METADATA +1 -7
- mapFolding-0.3.10.dist-info/RECORD +40 -0
- tests/conftest.py +2 -43
- tests/test_oeis.py +7 -66
- tests/test_other.py +30 -29
- mapFolding/someAssemblyRequired/synthesizeModuleJobNumba.py +0 -212
- mapFolding/syntheticModules/__init__.py +0 -3
- mapFolding-0.3.9.dist-info/RECORD +0 -40
- {mapFolding-0.3.9.dist-info → mapFolding-0.3.10.dist-info}/LICENSE +0 -0
- {mapFolding-0.3.9.dist-info → mapFolding-0.3.10.dist-info}/WHEEL +0 -0
- {mapFolding-0.3.9.dist-info → mapFolding-0.3.10.dist-info}/entry_points.txt +0 -0
- {mapFolding-0.3.9.dist-info → mapFolding-0.3.10.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
from mapFolding import indexMy, indexTrack
|
|
2
|
-
from numpy import integer
|
|
3
|
-
from numpy.typing import NDArray
|
|
2
|
+
from numpy import dtype, integer, ndarray
|
|
4
3
|
from typing import Any, Tuple
|
|
5
4
|
import numba
|
|
6
5
|
import numpy
|
|
@@ -8,24 +7,22 @@ from mapFolding.syntheticModules.numba_countInitialize import countInitialize
|
|
|
8
7
|
from mapFolding.syntheticModules.numba_countParallel import countParallel
|
|
9
8
|
from mapFolding.syntheticModules.numba_countSequential import countSequential
|
|
10
9
|
|
|
11
|
-
@numba.jit((numba.uint8[:, :, ::1], numba.int64[::1], numba.uint8[::1], numba.uint8[::1], numba.uint8[::1], numba.uint8[:, ::1]))
|
|
12
|
-
def doTheNeedful(connectionGraph:
|
|
13
|
-
"""
|
|
14
|
-
What in tarnation is this stupid module and function?
|
|
10
|
+
@numba.jit((numba.uint8[:, :, ::1], numba.int64[::1], numba.uint8[::1], numba.uint8[::1], numba.uint8[::1], numba.uint8[:, ::1]), _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)
|
|
11
|
+
def doTheNeedful(connectionGraph: ndarray[Tuple[int, int, int], dtype[integer[Any]]], foldGroups: ndarray[Tuple[int], dtype[integer[Any]]], gapsWhere: ndarray[Tuple[int], dtype[integer[Any]]], mapShape: ndarray[Tuple[int], dtype[integer[Any]]], my: ndarray[Tuple[int], dtype[integer[Any]]], track: ndarray[Tuple[int, int], dtype[integer[Any]]]) -> None:
|
|
12
|
+
"""What in tarnation is this stupid module and function?
|
|
15
13
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
"""
|
|
14
|
+
- This function is not in the same module as `countFolds` so that we can delay Numba just-in-time (jit) compilation of this function and the finalization of its settings until we are ready.
|
|
15
|
+
- This function is not in the same module as the next function, which does the hard work, so that we can delay `numba.jit` compilation of the next function.
|
|
16
|
+
- This function is "jitted" but the next function is super jitted, which makes it too arrogant to talk to plebian Python functions. It will, however, reluctantly talk to basic jitted functions.
|
|
17
|
+
- So this module can talk to the next function, and because this module isn't as arrogant, it will talk to the low-class `countFolds` that called this function. Well, with a few restrictions, of course:
|
|
18
|
+
- No `TypedDict`
|
|
19
|
+
- The plebs must clean up their own memory problems
|
|
20
|
+
- No oversized integers
|
|
21
|
+
- No global variables, only global constants
|
|
22
|
+
- It won't accept pleb nonlocal variables either
|
|
23
|
+
- Python "class": they are all inferior to the jit class
|
|
24
|
+
- No `**kwargs`
|
|
25
|
+
- and just a few dozen-jillion other things."""
|
|
29
26
|
countInitialize(connectionGraph, gapsWhere, my, track)
|
|
30
27
|
if my[indexMy.taskDivisions.value] > 0:
|
|
31
28
|
countParallel(connectionGraph, foldGroups, gapsWhere, my, track)
|
mapFolding/theDao.py
CHANGED
|
@@ -1,94 +1,93 @@
|
|
|
1
1
|
from mapFolding import indexMy, indexTrack
|
|
2
|
-
from numpy import integer
|
|
3
|
-
from numpy.typing import NDArray
|
|
2
|
+
from numpy import dtype, integer, ndarray
|
|
4
3
|
from typing import Any, Tuple
|
|
5
4
|
import numba
|
|
6
5
|
import numpy
|
|
7
6
|
|
|
8
|
-
def activeGapIncrement(my:
|
|
7
|
+
def activeGapIncrement(my: ndarray[Tuple[int], dtype[integer[Any]]]) -> None:
|
|
9
8
|
my[indexMy.gap1ndex.value] += 1
|
|
10
9
|
|
|
11
|
-
def activeLeafGreaterThan0Condition(my:
|
|
10
|
+
def activeLeafGreaterThan0Condition(my: ndarray[Tuple[int], dtype[integer[Any]]]) -> Any:
|
|
12
11
|
return my[indexMy.leaf1ndex.value]
|
|
13
12
|
|
|
14
|
-
def activeLeafGreaterThanLeavesTotalCondition(foldGroups:
|
|
13
|
+
def activeLeafGreaterThanLeavesTotalCondition(foldGroups: ndarray[Tuple[int], dtype[integer[Any]]], my: ndarray[Tuple[int], dtype[integer[Any]]]) -> Any:
|
|
15
14
|
return my[indexMy.leaf1ndex.value] > foldGroups[-1]
|
|
16
15
|
|
|
17
|
-
def activeLeafIsTheFirstLeafCondition(my:
|
|
16
|
+
def activeLeafIsTheFirstLeafCondition(my: ndarray[Tuple[int], dtype[integer[Any]]]) -> Any:
|
|
18
17
|
return my[indexMy.leaf1ndex.value] <= 1
|
|
19
18
|
|
|
20
|
-
def allDimensionsAreUnconstrained(my:
|
|
19
|
+
def allDimensionsAreUnconstrained(my: ndarray[Tuple[int], dtype[integer[Any]]]) -> Any:
|
|
21
20
|
return not my[indexMy.dimensionsUnconstrained.value]
|
|
22
21
|
|
|
23
|
-
def backtrack(my:
|
|
22
|
+
def backtrack(my: ndarray[Tuple[int], dtype[integer[Any]]], track: ndarray[Tuple[int, int], dtype[integer[Any]]]) -> None:
|
|
24
23
|
my[indexMy.leaf1ndex.value] -= 1
|
|
25
24
|
track[indexTrack.leafBelow.value, track[indexTrack.leafAbove.value, my[indexMy.leaf1ndex.value]]] = track[indexTrack.leafBelow.value, my[indexMy.leaf1ndex.value]]
|
|
26
25
|
track[indexTrack.leafAbove.value, track[indexTrack.leafBelow.value, my[indexMy.leaf1ndex.value]]] = track[indexTrack.leafAbove.value, my[indexMy.leaf1ndex.value]]
|
|
27
26
|
|
|
28
|
-
def backtrackCondition(my:
|
|
27
|
+
def backtrackCondition(my: ndarray[Tuple[int], dtype[integer[Any]]], track: ndarray[Tuple[int, int], dtype[integer[Any]]]) -> Any:
|
|
29
28
|
return my[indexMy.leaf1ndex.value] and my[indexMy.gap1ndex.value] == track[indexTrack.gapRangeStart.value, my[indexMy.leaf1ndex.value] - 1]
|
|
30
29
|
|
|
31
|
-
def gap1ndexCeilingIncrement(my:
|
|
30
|
+
def gap1ndexCeilingIncrement(my: ndarray[Tuple[int], dtype[integer[Any]]]) -> None:
|
|
32
31
|
my[indexMy.gap1ndexCeiling.value] += 1
|
|
33
32
|
|
|
34
|
-
def countGaps(gapsWhere:
|
|
33
|
+
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:
|
|
35
34
|
gapsWhere[my[indexMy.gap1ndexCeiling.value]] = my[indexMy.leafConnectee.value]
|
|
36
35
|
if track[indexTrack.countDimensionsGapped.value, my[indexMy.leafConnectee.value]] == 0:
|
|
37
36
|
gap1ndexCeilingIncrement(my=my)
|
|
38
37
|
track[indexTrack.countDimensionsGapped.value, my[indexMy.leafConnectee.value]] += 1
|
|
39
38
|
|
|
40
|
-
def dimension1ndexIncrement(my:
|
|
39
|
+
def dimension1ndexIncrement(my: ndarray[Tuple[int], dtype[integer[Any]]]) -> None:
|
|
41
40
|
my[indexMy.indexDimension.value] += 1
|
|
42
41
|
|
|
43
|
-
def dimensionsUnconstrainedCondition(connectionGraph:
|
|
42
|
+
def dimensionsUnconstrainedCondition(connectionGraph: ndarray[Tuple[int, int, int], dtype[integer[Any]]], my: ndarray[Tuple[int], dtype[integer[Any]]]) -> Any:
|
|
44
43
|
return connectionGraph[my[indexMy.indexDimension.value], my[indexMy.leaf1ndex.value], my[indexMy.leaf1ndex.value]] == my[indexMy.leaf1ndex.value]
|
|
45
44
|
|
|
46
|
-
def dimensionsUnconstrainedDecrement(my:
|
|
45
|
+
def dimensionsUnconstrainedDecrement(my: ndarray[Tuple[int], dtype[integer[Any]]]) -> None:
|
|
47
46
|
my[indexMy.dimensionsUnconstrained.value] -= 1
|
|
48
47
|
|
|
49
|
-
def filterCommonGaps(gapsWhere:
|
|
48
|
+
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:
|
|
50
49
|
gapsWhere[my[indexMy.gap1ndex.value]] = gapsWhere[my[indexMy.indexMiniGap.value]]
|
|
51
50
|
if track[indexTrack.countDimensionsGapped.value, gapsWhere[my[indexMy.indexMiniGap.value]]] == my[indexMy.dimensionsUnconstrained.value]:
|
|
52
51
|
activeGapIncrement(my=my)
|
|
53
52
|
track[indexTrack.countDimensionsGapped.value, gapsWhere[my[indexMy.indexMiniGap.value]]] = 0
|
|
54
53
|
|
|
55
|
-
def findGapsInitializeVariables(my:
|
|
54
|
+
def findGapsInitializeVariables(my: ndarray[Tuple[int], dtype[integer[Any]]], track: ndarray[Tuple[int, int], dtype[integer[Any]]]) -> None:
|
|
56
55
|
my[indexMy.dimensionsUnconstrained.value] = my[indexMy.dimensionsTotal.value]
|
|
57
56
|
my[indexMy.gap1ndexCeiling.value] = track[indexTrack.gapRangeStart.value, my[indexMy.leaf1ndex.value] - 1]
|
|
58
57
|
my[indexMy.indexDimension.value] = 0
|
|
59
58
|
|
|
60
|
-
def indexMiniGapIncrement(my:
|
|
59
|
+
def indexMiniGapIncrement(my: ndarray[Tuple[int], dtype[integer[Any]]]) -> None:
|
|
61
60
|
my[indexMy.indexMiniGap.value] += 1
|
|
62
61
|
|
|
63
|
-
def indexMiniGapInitialization(my:
|
|
62
|
+
def indexMiniGapInitialization(my: ndarray[Tuple[int], dtype[integer[Any]]]) -> None:
|
|
64
63
|
my[indexMy.indexMiniGap.value] = my[indexMy.gap1ndex.value]
|
|
65
64
|
|
|
66
|
-
def insertUnconstrainedLeaf(gapsWhere:
|
|
65
|
+
def insertUnconstrainedLeaf(gapsWhere: ndarray[Tuple[int], dtype[integer[Any]]], my: ndarray[Tuple[int], dtype[integer[Any]]]) -> None:
|
|
67
66
|
my[indexMy.indexLeaf.value] = 0
|
|
68
67
|
while my[indexMy.indexLeaf.value] < my[indexMy.leaf1ndex.value]:
|
|
69
68
|
gapsWhere[my[indexMy.gap1ndexCeiling.value]] = my[indexMy.indexLeaf.value]
|
|
70
69
|
my[indexMy.gap1ndexCeiling.value] += 1
|
|
71
70
|
my[indexMy.indexLeaf.value] += 1
|
|
72
71
|
|
|
73
|
-
def leafBelowSentinelIs1Condition(track:
|
|
72
|
+
def leafBelowSentinelIs1Condition(track: ndarray[Tuple[int, int], dtype[integer[Any]]]) -> Any:
|
|
74
73
|
return track[indexTrack.leafBelow.value, 0] == 1
|
|
75
74
|
|
|
76
|
-
def leafConnecteeInitialization(connectionGraph:
|
|
75
|
+
def leafConnecteeInitialization(connectionGraph: ndarray[Tuple[int, int, int], dtype[integer[Any]]], my: ndarray[Tuple[int], dtype[integer[Any]]]) -> None:
|
|
77
76
|
my[indexMy.leafConnectee.value] = connectionGraph[my[indexMy.indexDimension.value], my[indexMy.leaf1ndex.value], my[indexMy.leaf1ndex.value]]
|
|
78
77
|
|
|
79
|
-
def leafConnecteeUpdate(connectionGraph:
|
|
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:
|
|
80
79
|
my[indexMy.leafConnectee.value] = connectionGraph[my[indexMy.indexDimension.value], my[indexMy.leaf1ndex.value], track[indexTrack.leafBelow.value, my[indexMy.leafConnectee.value]]]
|
|
81
80
|
|
|
82
|
-
def loopingLeavesConnectedToActiveLeaf(my:
|
|
81
|
+
def loopingLeavesConnectedToActiveLeaf(my: ndarray[Tuple[int], dtype[integer[Any]]]) -> Any:
|
|
83
82
|
return my[indexMy.leafConnectee.value] != my[indexMy.leaf1ndex.value]
|
|
84
83
|
|
|
85
|
-
def loopingTheDimensions(my:
|
|
84
|
+
def loopingTheDimensions(my: ndarray[Tuple[int], dtype[integer[Any]]]) -> Any:
|
|
86
85
|
return my[indexMy.indexDimension.value] < my[indexMy.dimensionsTotal.value]
|
|
87
86
|
|
|
88
|
-
def loopingToActiveGapCeiling(my:
|
|
87
|
+
def loopingToActiveGapCeiling(my: ndarray[Tuple[int], dtype[integer[Any]]]) -> Any:
|
|
89
88
|
return my[indexMy.indexMiniGap.value] < my[indexMy.gap1ndexCeiling.value]
|
|
90
89
|
|
|
91
|
-
def placeLeaf(gapsWhere:
|
|
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:
|
|
92
91
|
my[indexMy.gap1ndex.value] -= 1
|
|
93
92
|
track[indexTrack.leafAbove.value, my[indexMy.leaf1ndex.value]] = gapsWhere[my[indexMy.gap1ndex.value]]
|
|
94
93
|
track[indexTrack.leafBelow.value, my[indexMy.leaf1ndex.value]] = track[indexTrack.leafBelow.value, track[indexTrack.leafAbove.value, my[indexMy.leaf1ndex.value]]]
|
|
@@ -97,16 +96,16 @@ def placeLeaf(gapsWhere: numpy.ndarray[Tuple[int], numpy.dtype[integer[Any]]], m
|
|
|
97
96
|
track[indexTrack.gapRangeStart.value, my[indexMy.leaf1ndex.value]] = my[indexMy.gap1ndex.value]
|
|
98
97
|
my[indexMy.leaf1ndex.value] += 1
|
|
99
98
|
|
|
100
|
-
def placeLeafCondition(my:
|
|
99
|
+
def placeLeafCondition(my: ndarray[Tuple[int], dtype[integer[Any]]]) -> Any:
|
|
101
100
|
return my[indexMy.leaf1ndex.value]
|
|
102
101
|
|
|
103
|
-
def thereAreComputationDivisionsYouMightSkip(my:
|
|
102
|
+
def thereAreComputationDivisionsYouMightSkip(my: ndarray[Tuple[int], dtype[integer[Any]]]) -> Any:
|
|
104
103
|
return my[indexMy.leaf1ndex.value] != my[indexMy.taskDivisions.value] or my[indexMy.leafConnectee.value] % my[indexMy.taskDivisions.value] == my[indexMy.taskIndex.value]
|
|
105
104
|
|
|
106
|
-
def countInitialize(connectionGraph:
|
|
107
|
-
, gapsWhere:
|
|
108
|
-
, my:
|
|
109
|
-
, track:
|
|
105
|
+
def countInitialize(connectionGraph: ndarray[Tuple[int, int, int], dtype[integer[Any]]]
|
|
106
|
+
, gapsWhere: ndarray[Tuple[int], dtype[integer[Any]]]
|
|
107
|
+
, my: ndarray[Tuple[int], dtype[integer[Any]]]
|
|
108
|
+
, track: ndarray[Tuple[int, int], dtype[integer[Any]]]) -> None:
|
|
110
109
|
while activeLeafGreaterThan0Condition(my=my):
|
|
111
110
|
if activeLeafIsTheFirstLeafCondition(my=my) or leafBelowSentinelIs1Condition(track=track):
|
|
112
111
|
findGapsInitializeVariables(my=my, track=track)
|
|
@@ -130,11 +129,11 @@ def countInitialize(connectionGraph: numpy.ndarray[Tuple[int, int, int], numpy.d
|
|
|
130
129
|
if my[indexMy.gap1ndex.value] > 0:
|
|
131
130
|
return
|
|
132
131
|
|
|
133
|
-
def countParallel(connectionGraph:
|
|
134
|
-
, foldGroups:
|
|
135
|
-
, gapsWhere:
|
|
136
|
-
, my:
|
|
137
|
-
, track:
|
|
132
|
+
def countParallel(connectionGraph: ndarray[Tuple[int, int, int], dtype[integer[Any]]]
|
|
133
|
+
, foldGroups: ndarray[Tuple[int], dtype[integer[Any]]]
|
|
134
|
+
, gapsWhere: ndarray[Tuple[int], dtype[integer[Any]]]
|
|
135
|
+
, my: ndarray[Tuple[int], dtype[integer[Any]]]
|
|
136
|
+
, track: ndarray[Tuple[int, int], dtype[integer[Any]]]) -> None:
|
|
138
137
|
gapsWherePARALLEL = gapsWhere.copy()
|
|
139
138
|
myPARALLEL = my.copy()
|
|
140
139
|
trackPARALLEL = track.copy()
|
|
@@ -171,7 +170,7 @@ def countParallel(connectionGraph: numpy.ndarray[Tuple[int, int, int], numpy.dty
|
|
|
171
170
|
placeLeaf(gapsWhere=gapsWhere, my=my, track=track)
|
|
172
171
|
foldGroups[my[indexMy.taskIndex.value]] = groupsOfFolds
|
|
173
172
|
|
|
174
|
-
def countSequential(connectionGraph:
|
|
173
|
+
def countSequential(connectionGraph: ndarray[Tuple[int, int, int], dtype[integer[Any]]], foldGroups: ndarray[Tuple[int], dtype[integer[Any]]], gapsWhere: ndarray[Tuple[int], dtype[integer[Any]]], my: ndarray[Tuple[int], dtype[integer[Any]]], track: ndarray[Tuple[int, int], dtype[integer[Any]]]) -> None:
|
|
175
174
|
groupsOfFolds: int = 0
|
|
176
175
|
doFindGaps = True
|
|
177
176
|
while activeLeafGreaterThan0Condition(my=my):
|
|
@@ -199,12 +198,12 @@ def countSequential(connectionGraph: numpy.ndarray[Tuple[int, int, int], numpy.d
|
|
|
199
198
|
placeLeaf(gapsWhere=gapsWhere, my=my, track=track)
|
|
200
199
|
foldGroups[my[indexMy.taskIndex.value]] = groupsOfFolds
|
|
201
200
|
|
|
202
|
-
def doTheNeedful(connectionGraph:
|
|
203
|
-
, foldGroups:
|
|
204
|
-
, gapsWhere:
|
|
205
|
-
, mapShape:
|
|
206
|
-
, my:
|
|
207
|
-
, track:
|
|
201
|
+
def doTheNeedful(connectionGraph: ndarray[Tuple[int, int, int], dtype[integer[Any]]]
|
|
202
|
+
, foldGroups: ndarray[Tuple[int], dtype[integer[Any]]]
|
|
203
|
+
, gapsWhere: ndarray[Tuple[int], dtype[integer[Any]]]
|
|
204
|
+
, mapShape: ndarray[Tuple[int], dtype[integer[Any]]]
|
|
205
|
+
, my: ndarray[Tuple[int], dtype[integer[Any]]]
|
|
206
|
+
, track: ndarray[Tuple[int, int], dtype[integer[Any]]]
|
|
208
207
|
) -> None:
|
|
209
208
|
countInitialize(connectionGraph, gapsWhere, my, track)
|
|
210
209
|
|
mapFolding/theSSOT.py
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
from collections import defaultdict
|
|
2
|
+
from mapFolding.theSSOTnumba import *
|
|
2
3
|
from numpy import integer
|
|
3
4
|
from types import ModuleType
|
|
4
|
-
from typing import Any, Callable, Dict, Final, Optional, Tuple, Type,
|
|
5
|
+
from typing import Any, Callable, Dict, Final, Optional, Tuple, Type, TYPE_CHECKING, cast
|
|
5
6
|
import enum
|
|
6
7
|
import numba
|
|
7
8
|
import numpy
|
|
@@ -9,6 +10,16 @@ import numpy.typing
|
|
|
9
10
|
import pathlib
|
|
10
11
|
import sys
|
|
11
12
|
|
|
13
|
+
try:
|
|
14
|
+
from typing import NotRequired
|
|
15
|
+
except ImportError:
|
|
16
|
+
from typing_extensions import NotRequired
|
|
17
|
+
|
|
18
|
+
if TYPE_CHECKING:
|
|
19
|
+
from typing import TypedDict
|
|
20
|
+
else:
|
|
21
|
+
TypedDict = dict
|
|
22
|
+
|
|
12
23
|
"""I have hobbled together:
|
|
13
24
|
TypedDict, Enum, defaultdict, and lookup dictionaries to make DIY immutability and delayed realization/instantiation.
|
|
14
25
|
Nevertheless, I am both confident that all of these processes will be replaced and completely ignorant of what will replace them."""
|
|
@@ -39,7 +50,7 @@ def getPathPackage() -> pathlib.Path:
|
|
|
39
50
|
pathPackage = pathPackage.parent
|
|
40
51
|
return pathPackage
|
|
41
52
|
|
|
42
|
-
def
|
|
53
|
+
def getPathJobRootDEFAULT() -> pathlib.Path:
|
|
43
54
|
if 'google.colab' in sys.modules:
|
|
44
55
|
pathJobDEFAULT = pathlib.Path("/content/drive/MyDrive") / "jobs"
|
|
45
56
|
else:
|
|
@@ -105,35 +116,6 @@ class indexTrack(EnumIndices):
|
|
|
105
116
|
countDimensionsGapped = enum.auto()
|
|
106
117
|
gapRangeStart = enum.auto()
|
|
107
118
|
|
|
108
|
-
class ParametersNumba(TypedDict):
|
|
109
|
-
_nrt: bool
|
|
110
|
-
boundscheck: bool
|
|
111
|
-
cache: bool
|
|
112
|
-
error_model: str
|
|
113
|
-
fastmath: bool
|
|
114
|
-
forceinline: bool
|
|
115
|
-
inline: str
|
|
116
|
-
looplift: bool
|
|
117
|
-
no_cfunc_wrapper: bool
|
|
118
|
-
no_cpython_wrapper: bool
|
|
119
|
-
nopython: bool
|
|
120
|
-
parallel: bool
|
|
121
|
-
|
|
122
|
-
parametersNumbaDEFAULT: Final[ParametersNumba] = {
|
|
123
|
-
'_nrt': True,
|
|
124
|
-
'boundscheck': False,
|
|
125
|
-
'cache': True,
|
|
126
|
-
'error_model': 'numpy',
|
|
127
|
-
'fastmath': True,
|
|
128
|
-
'forceinline': False,
|
|
129
|
-
'inline': 'never',
|
|
130
|
-
'looplift': False,
|
|
131
|
-
'no_cfunc_wrapper': True,
|
|
132
|
-
'no_cpython_wrapper': True,
|
|
133
|
-
'nopython': True,
|
|
134
|
-
'parallel': False,
|
|
135
|
-
}
|
|
136
|
-
|
|
137
119
|
"delay realization/instantiation until a concrete value is desired"
|
|
138
120
|
"moment of truth: when the value is needed, not when the value is defined"
|
|
139
121
|
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"""TODO learn how to use this efficiently and effectively to solve problems, be DRY, and have SSOT."""
|
|
2
|
+
from typing import Final, TYPE_CHECKING, Dict, Any, Union, Callable, Tuple, Any
|
|
3
|
+
import numba
|
|
4
|
+
import numba.core.compiler
|
|
5
|
+
try:
|
|
6
|
+
from typing import NotRequired
|
|
7
|
+
except ImportError:
|
|
8
|
+
from typing_extensions import NotRequired
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from typing import TypedDict
|
|
12
|
+
else:
|
|
13
|
+
TypedDict = dict
|
|
14
|
+
|
|
15
|
+
"""
|
|
16
|
+
Old notes that are not entirely accurate.
|
|
17
|
+
|
|
18
|
+
| **Option** | **Description** | **Why** | **Size** | **But** |
|
|
19
|
+
| ----------------------- | --------------------------------------------------- | --------------------- | --------------- | ------------------------ |
|
|
20
|
+
| `_dbg_extend_lifetimes` | Debug option to extend object lifetimes | Debugging | | |
|
|
21
|
+
| `_dbg_optnone` | Disable optimization for debugging | Debugging | | |
|
|
22
|
+
| `debug` | Enable debug mode with additional checks | Debugging | | |
|
|
23
|
+
| `no_rewrites` | Disable AST rewrites optimization | Debugging | | |
|
|
24
|
+
| `boundscheck` | Enable array bounds checking (slows execution) | Error checking | Larger | Slower |
|
|
25
|
+
| `error_model` | Divide by zero: kill or chill? | Error checking | ? | |
|
|
26
|
+
| `_nrt` | Enable No Runtime type checking | Startup speed | Smaller | No type protection |
|
|
27
|
+
| `fastmath` | Reduce float potential precision | Float speed | Smaller | Discriminatory, untested |
|
|
28
|
+
| `forceinline` | Force function inlining | Reduce function calls | Likely larger | |
|
|
29
|
+
| `forceobj` | Force object mode compilation | Inclusiveness | Larger | Slower execution |
|
|
30
|
+
| `inline` | Algorithmically choose inlining | Speed | Slightly larger | |
|
|
31
|
+
| `looplift` | Enable loop lifting optimization | Speed (if applicable) | Larger | Exclusionary |
|
|
32
|
+
| `no_cfunc_wrapper` | Disable C function wrapper generation | Size | Smaller | Exclusionary |
|
|
33
|
+
| `no_cpython_wrapper` | Disable Python C-API wrapper generation | Size | Smallest | Exclusionary |
|
|
34
|
+
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
# TODO try to implement all possible parameters, but use `NotRequired` for the more esoteric ones
|
|
38
|
+
class ParametersNumba(TypedDict):
|
|
39
|
+
_dbg_extend_lifetimes: NotRequired[bool]
|
|
40
|
+
_dbg_optnone: NotRequired[bool]
|
|
41
|
+
_nrt: NotRequired[bool]
|
|
42
|
+
boundscheck: NotRequired[bool]
|
|
43
|
+
cache: bool
|
|
44
|
+
debug: NotRequired[bool]
|
|
45
|
+
error_model: str
|
|
46
|
+
fastmath: bool
|
|
47
|
+
forceinline: bool
|
|
48
|
+
forceobj: NotRequired[bool]
|
|
49
|
+
inline: str
|
|
50
|
+
locals: NotRequired[Dict[str, Any]]
|
|
51
|
+
looplift: bool
|
|
52
|
+
no_cfunc_wrapper: bool
|
|
53
|
+
no_cpython_wrapper: bool
|
|
54
|
+
no_rewrites: NotRequired[bool]
|
|
55
|
+
nogil: NotRequired[bool]
|
|
56
|
+
nopython: bool
|
|
57
|
+
parallel: bool
|
|
58
|
+
pipeline_class: NotRequired[numba.core.compiler.CompilerBase]
|
|
59
|
+
signature_or_function: NotRequired[Union[Any, Callable, str, Tuple]]
|
|
60
|
+
target: NotRequired[str]
|
|
61
|
+
|
|
62
|
+
parametersNumbaFailEarly: Final[ParametersNumba] = {
|
|
63
|
+
'_nrt': True,
|
|
64
|
+
'boundscheck': True,
|
|
65
|
+
'cache': True,
|
|
66
|
+
'error_model': 'python',
|
|
67
|
+
'fastmath': False,
|
|
68
|
+
'forceinline': True,
|
|
69
|
+
'inline': 'always',
|
|
70
|
+
'looplift': False,
|
|
71
|
+
'no_cfunc_wrapper': False,
|
|
72
|
+
'no_cpython_wrapper': False,
|
|
73
|
+
'nopython': True,
|
|
74
|
+
'parallel': False,
|
|
75
|
+
}
|
|
76
|
+
"""For a production function: speed is irrelevant, error discovery is paramount, must be compatible with anything downstream."""
|
|
77
|
+
|
|
78
|
+
parametersNumbaDEFAULT: Final[ParametersNumba] = {
|
|
79
|
+
'_nrt': True,
|
|
80
|
+
'boundscheck': False,
|
|
81
|
+
'cache': True,
|
|
82
|
+
'error_model': 'numpy',
|
|
83
|
+
'fastmath': True,
|
|
84
|
+
'forceinline': True,
|
|
85
|
+
'inline': 'always',
|
|
86
|
+
'looplift': False,
|
|
87
|
+
'no_cfunc_wrapper': False,
|
|
88
|
+
'no_cpython_wrapper': False,
|
|
89
|
+
'nopython': True,
|
|
90
|
+
'parallel': False,
|
|
91
|
+
}
|
|
92
|
+
"""Middle of the road: fast, lean, but will talk to non-jitted functions."""
|
|
93
|
+
|
|
94
|
+
parametersNumbaParallelDEFAULT: Final[ParametersNumba] = {
|
|
95
|
+
**parametersNumbaDEFAULT,
|
|
96
|
+
'_nrt': True,
|
|
97
|
+
'parallel': True,
|
|
98
|
+
}
|
|
99
|
+
"""Middle of the road: fast, lean, but will talk to non-jitted functions."""
|
|
100
|
+
|
|
101
|
+
parametersNumbaSuperJit: Final[ParametersNumba] = {
|
|
102
|
+
**parametersNumbaDEFAULT,
|
|
103
|
+
'no_cfunc_wrapper': True,
|
|
104
|
+
'no_cpython_wrapper': True,
|
|
105
|
+
}
|
|
106
|
+
"""Speed, no helmet, no talking to non-jitted functions."""
|
|
107
|
+
|
|
108
|
+
parametersNumbaSuperJitParallel: Final[ParametersNumba] = {
|
|
109
|
+
**parametersNumbaSuperJit,
|
|
110
|
+
'_nrt': True,
|
|
111
|
+
'parallel': True,
|
|
112
|
+
}
|
|
113
|
+
"""Speed, no helmet, concurrency, no talking to non-jitted functions.
|
|
114
|
+
Claude says, "The NRT is Numba's memory management system that handles memory allocation and deallocation for array operations. Because of array copying, you need to have NRT enabled." IDK which AI assistant autocompleted this, but, "The NRT is a bit slower than the default memory management system, but it's necessary for certain operations."
|
|
115
|
+
"""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: mapFolding
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.10
|
|
4
4
|
Summary: Count distinct ways to fold a map (or a strip of stamps)
|
|
5
5
|
Author-email: Hunter Hogan <HunterHogan@pm.me>
|
|
6
6
|
License: CC-BY-NC-4.0
|
|
@@ -25,11 +25,6 @@ License-File: LICENSE
|
|
|
25
25
|
Requires-Dist: numba
|
|
26
26
|
Requires-Dist: numpy
|
|
27
27
|
Requires-Dist: Z0Z_tools
|
|
28
|
-
Provides-Extra: benchmark
|
|
29
|
-
Requires-Dist: ipywidgets; extra == "benchmark"
|
|
30
|
-
Requires-Dist: jupyter; extra == "benchmark"
|
|
31
|
-
Requires-Dist: pandas; extra == "benchmark"
|
|
32
|
-
Requires-Dist: tqdm; extra == "benchmark"
|
|
33
28
|
Provides-Extra: testing
|
|
34
29
|
Requires-Dist: more_itertools; extra == "testing"
|
|
35
30
|
Requires-Dist: mypy; extra == "testing"
|
|
@@ -39,7 +34,6 @@ Requires-Dist: pytest-mypy; extra == "testing"
|
|
|
39
34
|
Requires-Dist: pytest-xdist; extra == "testing"
|
|
40
35
|
Requires-Dist: pytest; extra == "testing"
|
|
41
36
|
Requires-Dist: python_minifier; extra == "testing"
|
|
42
|
-
Requires-Dist: tomli; extra == "testing"
|
|
43
37
|
Requires-Dist: types-setuptools; extra == "testing"
|
|
44
38
|
|
|
45
39
|
# Algorithm(s) for counting distinct ways to fold a map (or a strip of stamps)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
mapFolding/__init__.py,sha256=-6hIljicU0Ql3yWpw8prpLGSQGUCHsNrSuf7zDNs_Ko,1169
|
|
2
|
+
mapFolding/basecamp.py,sha256=DISWQIzAF7o7WPUn2QZxMu3Ruwc0zkVPgceeUTUcfqo,3988
|
|
3
|
+
mapFolding/beDRY.py,sha256=Gsj7NEBztbPoKszPibhW6pO9xwjAIPgaW411A_Quwz8,18654
|
|
4
|
+
mapFolding/oeis.py,sha256=2kFIAnBu0Bs4rHceXqs1RyyEBM6A_5fR5562B4ShxVg,12311
|
|
5
|
+
mapFolding/theDao.py,sha256=0ySeHdmNXA1X3aKs7tdJ1cQes_rWf9Vp0tdC1zSXf6U,13669
|
|
6
|
+
mapFolding/theSSOT.py,sha256=vtqhR1E6wwqVKtGKBY0UBAGRYu6x3gtPBloBzzuZi6M,9826
|
|
7
|
+
mapFolding/theSSOTnumba.py,sha256=ex_NnkGd3GWUQVrtWxKzsNmiSm2e091uhVmiZn0aPew,5568
|
|
8
|
+
mapFolding/reference/flattened.py,sha256=6blZ2Y9G8mu1F3gV8SKndPE398t2VVFlsgKlyeJ765A,16538
|
|
9
|
+
mapFolding/reference/hunterNumba.py,sha256=HWndRgsajOf76rbb2LDNEZ6itsdYbyV-k3wgOFjeR6c,7104
|
|
10
|
+
mapFolding/reference/irvineJavaPort.py,sha256=Sj-63Z-OsGuDoEBXuxyjRrNmmyl0d7Yz_XuY7I47Oyg,4250
|
|
11
|
+
mapFolding/reference/jax.py,sha256=rojyK80lOATtbzxjGOHWHZngQa47CXCLJHZwIdN2MwI,14955
|
|
12
|
+
mapFolding/reference/lunnan.py,sha256=XEcql_gxvCCghb6Or3qwmPbn4IZUbZTaSmw_fUjRxZE,5037
|
|
13
|
+
mapFolding/reference/lunnanNumpy.py,sha256=HqDgSwTOZA-G0oophOEfc4zs25Mv4yw2aoF1v8miOLk,4653
|
|
14
|
+
mapFolding/reference/lunnanWhile.py,sha256=7NY2IKO5XBgol0aWWF_Fi-7oTL9pvu_z6lB0TF1uVHk,4063
|
|
15
|
+
mapFolding/reference/rotatedEntryPoint.py,sha256=z0QyDQtnMvXNj5ntWzzJUQUMFm1-xHGLVhtYzwmczUI,11530
|
|
16
|
+
mapFolding/reference/total_countPlus1vsPlusN.py,sha256=usenM8Yn_G1dqlPl7NKKkcnbohBZVZBXTQRm2S3_EDA,8106
|
|
17
|
+
mapFolding/someAssemblyRequired/__init__.py,sha256=O-r-Oy7HK8RtIhXjBo99BPn7kOY-zDo4r1X_B3CYscI,121
|
|
18
|
+
mapFolding/someAssemblyRequired/getLLVMforNoReason.py,sha256=FtJzw2pZS3A4NimWdZsegXaU-vKeCw8m67kcfb5wvGM,894
|
|
19
|
+
mapFolding/someAssemblyRequired/makeJob.py,sha256=j62UMwwGV3CtF0j6ByyCxOuRNDCtv3MqVGUEtBSsAfk,2589
|
|
20
|
+
mapFolding/someAssemblyRequired/synthesizeJobNumba.py,sha256=fwWjayhHyef9UxpjGDpLKoCvkvwtVMITKczlEedUXpE,19358
|
|
21
|
+
mapFolding/someAssemblyRequired/synthesizeModuleJAX.py,sha256=TU8lgoMr77pctvvmlfbT-XstQk4j6Jo8JcIuvAiCuMU,1316
|
|
22
|
+
mapFolding/someAssemblyRequired/synthesizeModulesNumba.py,sha256=hg6FOJbaJcsiWrqv6sTqkxaXYkR_TKPyLS8sJGqRQB0,26460
|
|
23
|
+
mapFolding/syntheticModules/numba_countInitialize.py,sha256=d_aptX7pbgLxiXJnr-t0W6znDXqX77r8clfKQOTZfBw,4210
|
|
24
|
+
mapFolding/syntheticModules/numba_countParallel.py,sha256=W1157Xd8xwLXpRK82OMgL7AyFu0jh70_dHhrZ0mtYIs,5416
|
|
25
|
+
mapFolding/syntheticModules/numba_countSequential.py,sha256=Se4FNea9XOEfTVRJkNNdJHpsKu0CcLJGKmqUHvMqmrU,3593
|
|
26
|
+
mapFolding/syntheticModules/numba_doTheNeedful.py,sha256=DyfNpKHWSUD6vqL3gcv80eLvKeibtUm8aa-Zu_weuqE,2521
|
|
27
|
+
tests/__init__.py,sha256=eg9smg-6VblOr0kisM40CpGnuDtU2JgEEWGDTFVOlW8,57
|
|
28
|
+
tests/conftest.py,sha256=tGRYkHfwVKGoMklBSQiTD8cTu-QL1wUSZd-52Xlnm50,7676
|
|
29
|
+
tests/conftest_tmpRegistry.py,sha256=0XpGe7s2aJcjdEAqKs10vceW0_JAaK-Rp1UoPaL-BIo,2450
|
|
30
|
+
tests/conftest_uniformTests.py,sha256=2v9UJbKgbrus3UyWXsanEHLksBskbnP0MD8iKVPaIBo,2178
|
|
31
|
+
tests/test_oeis.py,sha256=F89HJ27y54NXcR2wMeBS4ea6R7EaEqpF_GkcU-BrsK4,5694
|
|
32
|
+
tests/test_other.py,sha256=UpS0_WUfWA3wONuZwip5AMmzNmmBwYD7reQDZ9ziL_o,12224
|
|
33
|
+
tests/test_tasks.py,sha256=ap_tKjHUN95vjzKo3xzBAQ3kMbdMJ_XXbOv9YIBJ5pY,2826
|
|
34
|
+
tests/test_types.py,sha256=HklNCGThFiqQ89AOMkE7YkcfAPiZE32DpD3GMDUPQVc,177
|
|
35
|
+
mapFolding-0.3.10.dist-info/LICENSE,sha256=NxH5Y8BdC-gNU-WSMwim3uMbID2iNDXJz7fHtuTdXhk,19346
|
|
36
|
+
mapFolding-0.3.10.dist-info/METADATA,sha256=GYvtSr3qWSvPYIrPAlZuQZmUIxIVt0vkPYIn-X7WOnc,7690
|
|
37
|
+
mapFolding-0.3.10.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
38
|
+
mapFolding-0.3.10.dist-info/entry_points.txt,sha256=F3OUeZR1XDTpoH7k3wXuRb3KF_kXTTeYhu5AGK1SiOQ,146
|
|
39
|
+
mapFolding-0.3.10.dist-info/top_level.txt,sha256=1gP2vFaqPwHujGwb3UjtMlLEGN-943VSYFR7V4gDqW8,17
|
|
40
|
+
mapFolding-0.3.10.dist-info/RECORD,,
|
tests/conftest.py
CHANGED
|
@@ -18,7 +18,7 @@ from mapFolding import *
|
|
|
18
18
|
from mapFolding import basecamp
|
|
19
19
|
from mapFolding import getAlgorithmCallable, getDispatcherCallable
|
|
20
20
|
from mapFolding.beDRY import *
|
|
21
|
-
from mapFolding.oeis import _getFilenameOEISbFile, _getOEISidValues
|
|
21
|
+
from mapFolding.oeis import _getFilenameOEISbFile, _getOEISidValues, _getOEISidInformation
|
|
22
22
|
from mapFolding.oeis import *
|
|
23
23
|
from Z0Z_tools.pytestForYourUse import PytestFor_defineConcurrencyLimit, PytestFor_intInnit, PytestFor_oopsieKwargsie
|
|
24
24
|
from typing import Any, Callable, ContextManager, Dict, Generator, List, Optional, Sequence, Set, Tuple, Type, Union
|
|
@@ -40,7 +40,7 @@ def makeDictionaryFoldsTotalKnown() -> Dict[Tuple[int,...], int]:
|
|
|
40
40
|
dictionaryMapDimensionsToFoldsTotalKnown[tuple(dimensions)] = foldingsTotal
|
|
41
41
|
|
|
42
42
|
# Are we in a place that has jobs?
|
|
43
|
-
pathJobDEFAULT =
|
|
43
|
+
pathJobDEFAULT = getPathJobRootDEFAULT()
|
|
44
44
|
if pathJobDEFAULT.exists():
|
|
45
45
|
# Are there foldsTotal files?
|
|
46
46
|
for pathFilenameFoldsTotal in pathJobDEFAULT.rglob('*.foldsTotal'):
|
|
@@ -181,44 +181,3 @@ def useAlgorithmDirectly() -> Generator[None, Any, None]:
|
|
|
181
181
|
|
|
182
182
|
# Restore original function
|
|
183
183
|
basecamp.getDispatcherCallable = original_dispatcher
|
|
184
|
-
|
|
185
|
-
"""
|
|
186
|
-
Section: Prototype test structures before moving to uniformTests.py"""
|
|
187
|
-
|
|
188
|
-
def prototypeCacheTest(
|
|
189
|
-
expected: Any,
|
|
190
|
-
setupCacheFile: Optional[Callable[[pathlib.Path, str], None]],
|
|
191
|
-
oeisID: str,
|
|
192
|
-
pathCache: pathlib.Path
|
|
193
|
-
) -> None:
|
|
194
|
-
"""Template for tests involving OEIS cache operations.
|
|
195
|
-
|
|
196
|
-
Parameters
|
|
197
|
-
expected: Expected value or exception from _getOEISidValues
|
|
198
|
-
setupCacheFile: Function to prepare the cache file before test
|
|
199
|
-
oeisID: OEIS ID to test
|
|
200
|
-
pathCache: Temporary cache directory path
|
|
201
|
-
"""
|
|
202
|
-
pathFilenameCache = pathCache / _getFilenameOEISbFile(oeisID)
|
|
203
|
-
|
|
204
|
-
# Setup cache file if provided
|
|
205
|
-
if setupCacheFile:
|
|
206
|
-
setupCacheFile(pathFilenameCache, oeisID)
|
|
207
|
-
|
|
208
|
-
# Run test
|
|
209
|
-
try:
|
|
210
|
-
actual: Any = _getOEISidValues(oeisID)
|
|
211
|
-
messageActual = actual
|
|
212
|
-
except Exception as actualError:
|
|
213
|
-
actual = type(actualError)
|
|
214
|
-
messageActual = type(actualError).__name__
|
|
215
|
-
|
|
216
|
-
# Compare results
|
|
217
|
-
if isinstance(expected, type) and issubclass(expected, Exception):
|
|
218
|
-
messageExpected = expected.__name__
|
|
219
|
-
assert isinstance(actual, expected), uniformTestMessage(
|
|
220
|
-
messageExpected, messageActual, "_getOEISidValues", oeisID)
|
|
221
|
-
else:
|
|
222
|
-
messageExpected = expected
|
|
223
|
-
assert actual == expected, uniformTestMessage(
|
|
224
|
-
messageExpected, messageActual, "_getOEISidValues", oeisID)
|