mapFolding 0.3.9__py3-none-any.whl → 0.3.11__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/makeJob.py +5 -6
- mapFolding/someAssemblyRequired/synthesizeModuleJAX.py +2 -2
- mapFolding/someAssemblyRequired/synthesizeNumba.py +805 -0
- mapFolding/syntheticModules/numba_countInitialize.py +10 -7
- mapFolding/syntheticModules/numba_countParallel.py +14 -9
- mapFolding/syntheticModules/numba_countSequential.py +11 -7
- mapFolding/syntheticModules/numba_doTheNeedful.py +10 -23
- mapFolding/theDao.py +66 -50
- mapFolding/theSSOT.py +21 -39
- mapFolding/theSSOTnumba.py +116 -0
- {mapFolding-0.3.9.dist-info → mapFolding-0.3.11.dist-info}/METADATA +3 -7
- mapFolding-0.3.11.dist-info/RECORD +39 -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/someAssemblyRequired/synthesizeModulesNumba.py +0 -506
- mapFolding/syntheticModules/__init__.py +0 -3
- mapFolding-0.3.9.dist-info/RECORD +0 -40
- {mapFolding-0.3.9.dist-info → mapFolding-0.3.11.dist-info}/LICENSE +0 -0
- {mapFolding-0.3.9.dist-info → mapFolding-0.3.11.dist-info}/WHEEL +0 -0
- {mapFolding-0.3.9.dist-info → mapFolding-0.3.11.dist-info}/entry_points.txt +0 -0
- {mapFolding-0.3.9.dist-info → mapFolding-0.3.11.dist-info}/top_level.txt +0 -0
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
from
|
|
2
|
-
import
|
|
1
|
+
from mapFolding import indexMy
|
|
2
|
+
from mapFolding import indexTrack
|
|
3
|
+
from numba import uint8
|
|
4
|
+
from numba import jit
|
|
5
|
+
from numpy import ndarray
|
|
6
|
+
from numpy import dtype
|
|
3
7
|
from numpy import integer
|
|
4
|
-
import
|
|
5
|
-
from
|
|
6
|
-
from typing import Any, Tuple
|
|
8
|
+
from typing import Any
|
|
9
|
+
from typing import Tuple
|
|
7
10
|
|
|
8
|
-
@
|
|
9
|
-
def countInitialize(connectionGraph:
|
|
11
|
+
@jit((uint8[:, :, ::1], uint8[::1], uint8[::1], uint8[:, ::1]), _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)
|
|
12
|
+
def countInitialize(connectionGraph: ndarray[Tuple[int, int, 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:
|
|
10
13
|
while my[indexMy.leaf1ndex.value]:
|
|
11
14
|
if my[indexMy.leaf1ndex.value] <= 1 or track[indexTrack.leafBelow.value, 0] == 1:
|
|
12
15
|
my[indexMy.dimensionsUnconstrained.value] = my[indexMy.dimensionsTotal.value]
|
|
@@ -1,22 +1,27 @@
|
|
|
1
|
-
from
|
|
2
|
-
import
|
|
1
|
+
from mapFolding import indexMy
|
|
2
|
+
from mapFolding import indexTrack
|
|
3
|
+
from numba import uint8
|
|
4
|
+
from numba import prange
|
|
5
|
+
from numba import jit
|
|
6
|
+
from numba import int64
|
|
7
|
+
from numpy import ndarray
|
|
8
|
+
from numpy import dtype
|
|
3
9
|
from numpy import integer
|
|
4
|
-
import
|
|
5
|
-
from
|
|
6
|
-
from typing import Any, Tuple
|
|
10
|
+
from typing import Any
|
|
11
|
+
from typing import Tuple
|
|
7
12
|
|
|
8
|
-
@
|
|
9
|
-
def countParallel(connectionGraph:
|
|
13
|
+
@jit((uint8[:, :, ::1], int64[::1], uint8[::1], uint8[::1], uint8[:, ::1]), _nrt=True, boundscheck=False, cache=True, error_model='numpy', fastmath=True, forceinline=True, inline='always', looplift=False, no_cfunc_wrapper=True, no_cpython_wrapper=True, nopython=True, parallel=True)
|
|
14
|
+
def countParallel(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:
|
|
10
15
|
gapsWherePARALLEL = gapsWhere.copy()
|
|
11
16
|
myPARALLEL = my.copy()
|
|
12
17
|
trackPARALLEL = track.copy()
|
|
13
18
|
taskDivisionsPrange = myPARALLEL[indexMy.taskDivisions.value]
|
|
14
|
-
for indexSherpa in
|
|
19
|
+
for indexSherpa in prange(taskDivisionsPrange):
|
|
15
20
|
groupsOfFolds: int = 0
|
|
16
21
|
gapsWhere = gapsWherePARALLEL.copy()
|
|
17
22
|
my = myPARALLEL.copy()
|
|
18
|
-
my[indexMy.taskIndex.value] = indexSherpa
|
|
19
23
|
track = trackPARALLEL.copy()
|
|
24
|
+
my[indexMy.taskIndex.value] = indexSherpa
|
|
20
25
|
while my[indexMy.leaf1ndex.value]:
|
|
21
26
|
if my[indexMy.leaf1ndex.value] <= 1 or track[indexTrack.leafBelow.value, 0] == 1:
|
|
22
27
|
if my[indexMy.leaf1ndex.value] > foldGroups[-1]:
|
|
@@ -1,12 +1,16 @@
|
|
|
1
|
-
from
|
|
2
|
-
import
|
|
1
|
+
from mapFolding import indexMy
|
|
2
|
+
from mapFolding import indexTrack
|
|
3
|
+
from numba import uint8
|
|
4
|
+
from numba import jit
|
|
5
|
+
from numba import int64
|
|
6
|
+
from numpy import ndarray
|
|
7
|
+
from numpy import dtype
|
|
3
8
|
from numpy import integer
|
|
4
|
-
import
|
|
5
|
-
from
|
|
6
|
-
from typing import Any, Tuple
|
|
9
|
+
from typing import Any
|
|
10
|
+
from typing import Tuple
|
|
7
11
|
|
|
8
|
-
@
|
|
9
|
-
def countSequential(connectionGraph:
|
|
12
|
+
@jit((uint8[:, :, ::1], int64[::1], uint8[::1], uint8[::1], uint8[:, ::1]), _nrt=True, boundscheck=False, cache=True, error_model='numpy', fastmath=True, forceinline=True, inline='always', looplift=False, no_cfunc_wrapper=True, no_cpython_wrapper=True, nopython=True, parallel=False)
|
|
13
|
+
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:
|
|
10
14
|
leafBelow = track[indexTrack.leafBelow.value]
|
|
11
15
|
gapRangeStart = track[indexTrack.gapRangeStart.value]
|
|
12
16
|
countDimensionsGapped = track[indexTrack.countDimensionsGapped.value]
|
|
@@ -1,31 +1,18 @@
|
|
|
1
|
-
from mapFolding import indexMy
|
|
1
|
+
from mapFolding import indexMy
|
|
2
|
+
from numba import uint8
|
|
3
|
+
from numba import jit
|
|
4
|
+
from numba import int64
|
|
5
|
+
from numpy import ndarray
|
|
6
|
+
from numpy import dtype
|
|
2
7
|
from numpy import integer
|
|
3
|
-
from
|
|
4
|
-
from typing import
|
|
5
|
-
import numba
|
|
6
|
-
import numpy
|
|
8
|
+
from typing import Any
|
|
9
|
+
from typing import Tuple
|
|
7
10
|
from mapFolding.syntheticModules.numba_countInitialize import countInitialize
|
|
8
11
|
from mapFolding.syntheticModules.numba_countParallel import countParallel
|
|
9
12
|
from mapFolding.syntheticModules.numba_countSequential import countSequential
|
|
10
13
|
|
|
11
|
-
@
|
|
12
|
-
def doTheNeedful(connectionGraph:
|
|
13
|
-
"""
|
|
14
|
-
What in tarnation is this stupid module and function?
|
|
15
|
-
|
|
16
|
-
- 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.
|
|
17
|
-
- 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.
|
|
18
|
-
- 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.
|
|
19
|
-
- 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:
|
|
20
|
-
- No `TypedDict`
|
|
21
|
-
- The plebs must clean up their own memory problems
|
|
22
|
-
- No oversized integers
|
|
23
|
-
- No global variables, only global constants
|
|
24
|
-
- It won't accept pleb nonlocal variables either
|
|
25
|
-
- Python "class": they are all inferior to the jit class
|
|
26
|
-
- No `**kwargs`
|
|
27
|
-
- and just a few dozen-jillion other things.
|
|
28
|
-
"""
|
|
14
|
+
@jit((uint8[:, :, ::1], int64[::1], uint8[::1], uint8[::1], uint8[::1], 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)
|
|
15
|
+
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:
|
|
29
16
|
countInitialize(connectionGraph, gapsWhere, my, track)
|
|
30
17
|
if my[indexMy.taskDivisions.value] > 0:
|
|
31
18
|
countParallel(connectionGraph, foldGroups, gapsWhere, my, track)
|
mapFolding/theDao.py
CHANGED
|
@@ -1,94 +1,93 @@
|
|
|
1
1
|
from mapFolding import indexMy, indexTrack
|
|
2
|
-
from
|
|
3
|
-
from numpy
|
|
2
|
+
from numba import prange
|
|
3
|
+
from numpy import dtype, integer, ndarray
|
|
4
4
|
from typing import Any, Tuple
|
|
5
|
-
import numba
|
|
6
|
-
import numpy
|
|
7
5
|
|
|
8
|
-
def activeGapIncrement(my:
|
|
6
|
+
def activeGapIncrement(my: ndarray[Tuple[int], dtype[integer[Any]]]) -> None:
|
|
7
|
+
# `.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 index without `.value`.
|
|
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,18 @@ 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
|
-
|
|
108
|
-
|
|
109
|
-
|
|
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]]]
|
|
109
|
+
) -> None:
|
|
110
|
+
|
|
110
111
|
while activeLeafGreaterThan0Condition(my=my):
|
|
111
112
|
if activeLeafIsTheFirstLeafCondition(my=my) or leafBelowSentinelIs1Condition(track=track):
|
|
112
113
|
findGapsInitializeVariables(my=my, track=track)
|
|
@@ -130,21 +131,28 @@ def countInitialize(connectionGraph: numpy.ndarray[Tuple[int, int, int], numpy.d
|
|
|
130
131
|
if my[indexMy.gap1ndex.value] > 0:
|
|
131
132
|
return
|
|
132
133
|
|
|
133
|
-
def countParallel(connectionGraph:
|
|
134
|
-
,
|
|
135
|
-
,
|
|
136
|
-
,
|
|
137
|
-
,
|
|
134
|
+
def countParallel(connectionGraph: ndarray[Tuple[int, int, int], dtype[integer[Any]]]
|
|
135
|
+
, foldGroups: ndarray[Tuple[int] , dtype[integer[Any]]]
|
|
136
|
+
, gapsWhere: ndarray[Tuple[int] , dtype[integer[Any]]]
|
|
137
|
+
, my: ndarray[Tuple[int] , dtype[integer[Any]]]
|
|
138
|
+
, track: ndarray[Tuple[int, int] , dtype[integer[Any]]]
|
|
139
|
+
) -> None:
|
|
140
|
+
|
|
138
141
|
gapsWherePARALLEL = gapsWhere.copy()
|
|
139
142
|
myPARALLEL = my.copy()
|
|
140
143
|
trackPARALLEL = track.copy()
|
|
144
|
+
|
|
141
145
|
taskDivisionsPrange = myPARALLEL[indexMy.taskDivisions.value]
|
|
142
|
-
|
|
146
|
+
|
|
147
|
+
for indexSherpa in prange(taskDivisionsPrange):
|
|
143
148
|
groupsOfFolds: int = 0
|
|
149
|
+
|
|
144
150
|
gapsWhere = gapsWherePARALLEL.copy()
|
|
145
151
|
my = myPARALLEL.copy()
|
|
146
|
-
my[indexMy.taskIndex.value] = indexSherpa
|
|
147
152
|
track = trackPARALLEL.copy()
|
|
153
|
+
|
|
154
|
+
my[indexMy.taskIndex.value] = indexSherpa
|
|
155
|
+
|
|
148
156
|
while activeLeafGreaterThan0Condition(my=my):
|
|
149
157
|
if activeLeafIsTheFirstLeafCondition(my=my) or leafBelowSentinelIs1Condition(track=track):
|
|
150
158
|
if activeLeafGreaterThanLeavesTotalCondition(foldGroups=foldGroups, my=my):
|
|
@@ -171,9 +179,16 @@ def countParallel(connectionGraph: numpy.ndarray[Tuple[int, int, int], numpy.dty
|
|
|
171
179
|
placeLeaf(gapsWhere=gapsWhere, my=my, track=track)
|
|
172
180
|
foldGroups[my[indexMy.taskIndex.value]] = groupsOfFolds
|
|
173
181
|
|
|
174
|
-
def countSequential(connectionGraph:
|
|
182
|
+
def countSequential( connectionGraph: ndarray[Tuple[int, int, int], dtype[integer[Any]]]
|
|
183
|
+
, foldGroups: ndarray[Tuple[int] , dtype[integer[Any]]]
|
|
184
|
+
, gapsWhere: ndarray[Tuple[int] , dtype[integer[Any]]]
|
|
185
|
+
, my: ndarray[Tuple[int] , dtype[integer[Any]]]
|
|
186
|
+
, track: ndarray[Tuple[int, int] , dtype[integer[Any]]]
|
|
187
|
+
) -> None:
|
|
188
|
+
|
|
175
189
|
groupsOfFolds: int = 0
|
|
176
|
-
doFindGaps = True
|
|
190
|
+
doFindGaps = True # Frankly, I can't figure out if `doFindGaps` is or is not faster. Furthermore, I have a strong feeling there is an even better way.
|
|
191
|
+
|
|
177
192
|
while activeLeafGreaterThan0Condition(my=my):
|
|
178
193
|
if ((doFindGaps := activeLeafIsTheFirstLeafCondition(my=my) or leafBelowSentinelIs1Condition(track=track))
|
|
179
194
|
and activeLeafGreaterThanLeavesTotalCondition(foldGroups=foldGroups, my=my)):
|
|
@@ -199,13 +214,14 @@ def countSequential(connectionGraph: numpy.ndarray[Tuple[int, int, int], numpy.d
|
|
|
199
214
|
placeLeaf(gapsWhere=gapsWhere, my=my, track=track)
|
|
200
215
|
foldGroups[my[indexMy.taskIndex.value]] = groupsOfFolds
|
|
201
216
|
|
|
202
|
-
def doTheNeedful(connectionGraph:
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
217
|
+
def doTheNeedful(connectionGraph: ndarray[Tuple[int, int, int], dtype[integer[Any]]]
|
|
218
|
+
, foldGroups: ndarray[Tuple[int] , dtype[integer[Any]]]
|
|
219
|
+
, gapsWhere: ndarray[Tuple[int] , dtype[integer[Any]]]
|
|
220
|
+
, mapShape: ndarray[Tuple[int] , dtype[integer[Any]]]
|
|
221
|
+
, my: ndarray[Tuple[int] , dtype[integer[Any]]]
|
|
222
|
+
, track: ndarray[Tuple[int, int] , dtype[integer[Any]]]
|
|
223
|
+
) -> None:
|
|
224
|
+
|
|
209
225
|
countInitialize(connectionGraph, gapsWhere, my, track)
|
|
210
226
|
|
|
211
227
|
if my[indexMy.taskDivisions.value] > 0:
|
mapFolding/theSSOT.py
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
from collections import defaultdict
|
|
2
|
-
from
|
|
2
|
+
from mapFolding.theSSOTnumba import *
|
|
3
|
+
from numpy import dtype, integer, ndarray
|
|
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:
|
|
@@ -62,14 +73,14 @@ def getDispatcherCallable() -> Callable[..., None]:
|
|
|
62
73
|
from mapFolding.syntheticModules import numba_doTheNeedful
|
|
63
74
|
return cast(Callable[..., None], numba_doTheNeedful.doTheNeedful)
|
|
64
75
|
|
|
65
|
-
# NOTE I want this _concept_ to be well implemented and usable everywhere: Python, Numba, Jax, CUDA, idc
|
|
76
|
+
# NOTE I want this _concept_, not necessarily this method, to be well implemented and usable everywhere: Python, Numba, Jax, CUDA, idc
|
|
66
77
|
class computationState(TypedDict):
|
|
67
|
-
connectionGraph:
|
|
68
|
-
foldGroups:
|
|
69
|
-
gapsWhere:
|
|
70
|
-
mapShape:
|
|
71
|
-
my:
|
|
72
|
-
track:
|
|
78
|
+
connectionGraph: ndarray[Tuple[int, int, int], dtype[integer[Any]]]
|
|
79
|
+
foldGroups: ndarray[Tuple[int] , dtype[integer[Any]]]
|
|
80
|
+
gapsWhere: ndarray[Tuple[int] , dtype[integer[Any]]]
|
|
81
|
+
mapShape: ndarray[Tuple[int] , dtype[integer[Any]]]
|
|
82
|
+
my: ndarray[Tuple[int] , dtype[integer[Any]]]
|
|
83
|
+
track: ndarray[Tuple[int, int] , dtype[integer[Any]]]
|
|
73
84
|
|
|
74
85
|
@enum.verify(enum.CONTINUOUS, enum.UNIQUE) if sys.version_info >= (3, 11) else lambda x: x
|
|
75
86
|
class EnumIndices(enum.IntEnum):
|
|
@@ -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,116 @@
|
|
|
1
|
+
"""I have so much truth, I need two files to contain it all!"""
|
|
2
|
+
"""TODO learn how to use this efficiently and effectively to solve problems, be DRY, and have SSOT."""
|
|
3
|
+
from typing import Final, TYPE_CHECKING, Dict, Any, Union, Callable, Tuple, Any
|
|
4
|
+
import numba
|
|
5
|
+
import numba.core.compiler
|
|
6
|
+
try:
|
|
7
|
+
from typing import NotRequired
|
|
8
|
+
except ImportError:
|
|
9
|
+
from typing_extensions import NotRequired
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from typing import TypedDict
|
|
13
|
+
else:
|
|
14
|
+
TypedDict = dict
|
|
15
|
+
|
|
16
|
+
"""
|
|
17
|
+
Old notes that are not entirely accurate.
|
|
18
|
+
|
|
19
|
+
| **Option** | **Description** | **Why** | **Size** | **But** |
|
|
20
|
+
| ----------------------- | --------------------------------------------------- | --------------------- | --------------- | ------------------------ |
|
|
21
|
+
| `_dbg_extend_lifetimes` | Debug option to extend object lifetimes | Debugging | | |
|
|
22
|
+
| `_dbg_optnone` | Disable optimization for debugging | Debugging | | |
|
|
23
|
+
| `debug` | Enable debug mode with additional checks | Debugging | | |
|
|
24
|
+
| `no_rewrites` | Disable AST rewrites optimization | Debugging | | |
|
|
25
|
+
| `boundscheck` | Enable array bounds checking (slows execution) | Error checking | Larger | Slower |
|
|
26
|
+
| `error_model` | Divide by zero: kill or chill? | Error checking | ? | |
|
|
27
|
+
| `_nrt` | Enable No Runtime type checking | Startup speed | Smaller | No type protection |
|
|
28
|
+
| `fastmath` | Reduce float potential precision | Float speed | Smaller | Discriminatory, untested |
|
|
29
|
+
| `forceinline` | Force function inlining | Reduce function calls | Likely larger | |
|
|
30
|
+
| `forceobj` | Force object mode compilation | Inclusiveness | Larger | Slower execution |
|
|
31
|
+
| `inline` | Algorithmically choose inlining | Speed | Slightly larger | |
|
|
32
|
+
| `looplift` | Enable loop lifting optimization | Speed (if applicable) | Larger | Exclusionary |
|
|
33
|
+
| `no_cfunc_wrapper` | Disable C function wrapper generation | Size | Smaller | Exclusionary |
|
|
34
|
+
| `no_cpython_wrapper` | Disable Python C-API wrapper generation | Size | Smallest | Exclusionary |
|
|
35
|
+
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
# TODO try to implement all possible parameters, but use `NotRequired` for the more esoteric ones
|
|
39
|
+
class ParametersNumba(TypedDict):
|
|
40
|
+
_dbg_extend_lifetimes: NotRequired[bool]
|
|
41
|
+
_dbg_optnone: NotRequired[bool]
|
|
42
|
+
_nrt: NotRequired[bool]
|
|
43
|
+
boundscheck: NotRequired[bool]
|
|
44
|
+
cache: bool
|
|
45
|
+
debug: NotRequired[bool]
|
|
46
|
+
error_model: str
|
|
47
|
+
fastmath: bool
|
|
48
|
+
forceinline: bool
|
|
49
|
+
forceobj: NotRequired[bool]
|
|
50
|
+
inline: str
|
|
51
|
+
locals: NotRequired[Dict[str, Any]]
|
|
52
|
+
looplift: bool
|
|
53
|
+
no_cfunc_wrapper: bool
|
|
54
|
+
no_cpython_wrapper: bool
|
|
55
|
+
no_rewrites: NotRequired[bool]
|
|
56
|
+
nogil: NotRequired[bool]
|
|
57
|
+
nopython: bool
|
|
58
|
+
parallel: bool
|
|
59
|
+
pipeline_class: NotRequired[numba.core.compiler.CompilerBase]
|
|
60
|
+
signature_or_function: NotRequired[Union[Any, Callable, str, Tuple]]
|
|
61
|
+
target: NotRequired[str]
|
|
62
|
+
|
|
63
|
+
parametersNumbaFailEarly: Final[ParametersNumba] = {
|
|
64
|
+
'_nrt': True,
|
|
65
|
+
'boundscheck': True,
|
|
66
|
+
'cache': True,
|
|
67
|
+
'error_model': 'python',
|
|
68
|
+
'fastmath': False,
|
|
69
|
+
'forceinline': True,
|
|
70
|
+
'inline': 'always',
|
|
71
|
+
'looplift': False,
|
|
72
|
+
'no_cfunc_wrapper': False,
|
|
73
|
+
'no_cpython_wrapper': False,
|
|
74
|
+
'nopython': True,
|
|
75
|
+
'parallel': False,
|
|
76
|
+
}
|
|
77
|
+
"""For a production function: speed is irrelevant, error discovery is paramount, must be compatible with anything downstream."""
|
|
78
|
+
|
|
79
|
+
parametersNumbaDEFAULT: Final[ParametersNumba] = {
|
|
80
|
+
'_nrt': True,
|
|
81
|
+
'boundscheck': False,
|
|
82
|
+
'cache': True,
|
|
83
|
+
'error_model': 'numpy',
|
|
84
|
+
'fastmath': True,
|
|
85
|
+
'forceinline': True,
|
|
86
|
+
'inline': 'always',
|
|
87
|
+
'looplift': False,
|
|
88
|
+
'no_cfunc_wrapper': False,
|
|
89
|
+
'no_cpython_wrapper': False,
|
|
90
|
+
'nopython': True,
|
|
91
|
+
'parallel': False,
|
|
92
|
+
}
|
|
93
|
+
"""Middle of the road: fast, lean, but will talk to non-jitted functions."""
|
|
94
|
+
|
|
95
|
+
parametersNumbaParallelDEFAULT: Final[ParametersNumba] = {
|
|
96
|
+
**parametersNumbaDEFAULT,
|
|
97
|
+
'_nrt': True,
|
|
98
|
+
'parallel': True,
|
|
99
|
+
}
|
|
100
|
+
"""Middle of the road: fast, lean, but will talk to non-jitted functions."""
|
|
101
|
+
|
|
102
|
+
parametersNumbaSuperJit: Final[ParametersNumba] = {
|
|
103
|
+
**parametersNumbaDEFAULT,
|
|
104
|
+
'no_cfunc_wrapper': True,
|
|
105
|
+
'no_cpython_wrapper': True,
|
|
106
|
+
}
|
|
107
|
+
"""Speed, no helmet, no talking to non-jitted functions."""
|
|
108
|
+
|
|
109
|
+
parametersNumbaSuperJitParallel: Final[ParametersNumba] = {
|
|
110
|
+
**parametersNumbaSuperJit,
|
|
111
|
+
'_nrt': True,
|
|
112
|
+
'parallel': True,
|
|
113
|
+
}
|
|
114
|
+
"""Speed, no helmet, concurrency, no talking to non-jitted functions.
|
|
115
|
+
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."
|
|
116
|
+
"""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: mapFolding
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.11
|
|
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,12 +25,8 @@ 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
|
|
29
|
+
Requires-Dist: autoflake; extra == "testing"
|
|
34
30
|
Requires-Dist: more_itertools; extra == "testing"
|
|
35
31
|
Requires-Dist: mypy; extra == "testing"
|
|
36
32
|
Requires-Dist: pytest-cov; extra == "testing"
|
|
@@ -39,8 +35,8 @@ Requires-Dist: pytest-mypy; extra == "testing"
|
|
|
39
35
|
Requires-Dist: pytest-xdist; extra == "testing"
|
|
40
36
|
Requires-Dist: pytest; extra == "testing"
|
|
41
37
|
Requires-Dist: python_minifier; extra == "testing"
|
|
42
|
-
Requires-Dist: tomli; extra == "testing"
|
|
43
38
|
Requires-Dist: types-setuptools; extra == "testing"
|
|
39
|
+
Requires-Dist: updateCitation; extra == "testing"
|
|
44
40
|
|
|
45
41
|
# Algorithm(s) for counting distinct ways to fold a map (or a strip of stamps)
|
|
46
42
|
|