mapFolding 0.9.4__py3-none-any.whl → 0.9.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mapFolding/__init__.py +41 -7
- mapFolding/basecamp.py +100 -9
- mapFolding/beDRY.py +7 -15
- mapFolding/dataBaskets.py +12 -0
- mapFolding/datatypes.py +4 -4
- mapFolding/oeis.py +2 -7
- mapFolding/someAssemblyRequired/RecipeJob.py +97 -3
- mapFolding/someAssemblyRequired/Z0Z_makeSomeModules.py +112 -12
- mapFolding/someAssemblyRequired/__init__.py +26 -28
- mapFolding/someAssemblyRequired/_theTypes.py +13 -19
- mapFolding/someAssemblyRequired/_tool_Make.py +4 -6
- mapFolding/someAssemblyRequired/_tool_Then.py +17 -22
- mapFolding/someAssemblyRequired/_toolboxAntecedents.py +32 -15
- mapFolding/someAssemblyRequired/_toolboxContainers.py +124 -29
- mapFolding/someAssemblyRequired/makeJobTheorem2Numba.py +274 -0
- mapFolding/someAssemblyRequired/synthesizeNumbaJob.py +3 -2
- mapFolding/someAssemblyRequired/toolboxNumba.py +3 -27
- mapFolding/someAssemblyRequired/transformationTools.py +8 -120
- mapFolding/syntheticModules/daoOfMapFolding.py +74 -0
- mapFolding/syntheticModules/dataPacking.py +1 -1
- mapFolding/syntheticModules/theorem2Numba.py +2 -8
- mapFolding/syntheticModules/theorem2Trimmed.py +43 -0
- {mapfolding-0.9.4.dist-info → mapfolding-0.9.5.dist-info}/METADATA +1 -1
- {mapfolding-0.9.4.dist-info → mapfolding-0.9.5.dist-info}/RECORD +29 -27
- tests/test_computations.py +1 -1
- mapFolding/Z0Z_flowControl.py +0 -117
- {mapfolding-0.9.4.dist-info → mapfolding-0.9.5.dist-info}/WHEEL +0 -0
- {mapfolding-0.9.4.dist-info → mapfolding-0.9.5.dist-info}/entry_points.txt +0 -0
- {mapfolding-0.9.4.dist-info → mapfolding-0.9.5.dist-info}/licenses/LICENSE +0 -0
- {mapfolding-0.9.4.dist-info → mapfolding-0.9.5.dist-info}/top_level.txt +0 -0
mapFolding/__init__.py
CHANGED
|
@@ -44,7 +44,41 @@ allowing users to compute map folding totals for larger dimensions than previous
|
|
|
44
44
|
foundation for exploring advanced code transformation techniques.
|
|
45
45
|
"""
|
|
46
46
|
|
|
47
|
-
from
|
|
47
|
+
from typing import Any, TypeAlias
|
|
48
|
+
import sys
|
|
49
|
+
|
|
50
|
+
stuPyd: TypeAlias = Any
|
|
51
|
+
|
|
52
|
+
if sys.version_info >= (3, 12):
|
|
53
|
+
from ast import (
|
|
54
|
+
ParamSpec as astDOTParamSpec,
|
|
55
|
+
type_param as astDOTtype_param,
|
|
56
|
+
TypeAlias as astDOTTypeAlias,
|
|
57
|
+
TypeVar as astDOTTypeVar,
|
|
58
|
+
TypeVarTuple as astDOTTypeVarTuple,
|
|
59
|
+
)
|
|
60
|
+
else:
|
|
61
|
+
astDOTParamSpec: TypeAlias = stuPyd
|
|
62
|
+
astDOTtype_param: TypeAlias = stuPyd
|
|
63
|
+
astDOTTypeAlias: TypeAlias = stuPyd
|
|
64
|
+
astDOTTypeVar: TypeAlias = stuPyd
|
|
65
|
+
astDOTTypeVarTuple: TypeAlias = stuPyd
|
|
66
|
+
|
|
67
|
+
if sys.version_info >= (3, 11):
|
|
68
|
+
from ast import TryStar as astDOTTryStar
|
|
69
|
+
from typing import TypedDict as TypedDict
|
|
70
|
+
from typing import NotRequired as NotRequired
|
|
71
|
+
else:
|
|
72
|
+
astDOTTryStar: TypeAlias = stuPyd
|
|
73
|
+
try:
|
|
74
|
+
from typing_extensions import TypedDict as TypedDict
|
|
75
|
+
from typing_extensions import NotRequired as NotRequired
|
|
76
|
+
except Exception:
|
|
77
|
+
TypedDict = dict[stuPyd, stuPyd]
|
|
78
|
+
from collections.abc import Iterable
|
|
79
|
+
NotRequired: TypeAlias = Iterable
|
|
80
|
+
|
|
81
|
+
from mapFolding.datatypes import ( # noqa: E402
|
|
48
82
|
Array1DElephino as Array1DElephino,
|
|
49
83
|
Array1DFoldsTotal as Array1DFoldsTotal,
|
|
50
84
|
Array1DLeavesTotal as Array1DLeavesTotal,
|
|
@@ -58,18 +92,18 @@ from mapFolding.datatypes import (
|
|
|
58
92
|
NumPyLeavesTotal as NumPyLeavesTotal,
|
|
59
93
|
)
|
|
60
94
|
|
|
61
|
-
from mapFolding.theSSOT import (
|
|
95
|
+
from mapFolding.theSSOT import ( # noqa: E402
|
|
62
96
|
ComputationState as ComputationState,
|
|
63
97
|
raiseIfNoneGitHubIssueNumber3 as raiseIfNoneGitHubIssueNumber3,
|
|
64
98
|
The as The,
|
|
65
99
|
)
|
|
66
100
|
|
|
67
|
-
from mapFolding.theDao import (
|
|
101
|
+
from mapFolding.theDao import ( # noqa: E402
|
|
68
102
|
countInitialize as countInitialize,
|
|
69
103
|
doTheNeedful as doTheNeedful,
|
|
70
104
|
)
|
|
71
105
|
|
|
72
|
-
from mapFolding.beDRY import (
|
|
106
|
+
from mapFolding.beDRY import ( # noqa: E402
|
|
73
107
|
getLeavesTotal as getLeavesTotal,
|
|
74
108
|
getTaskDivisions as getTaskDivisions,
|
|
75
109
|
outfitCountFolds as outfitCountFolds,
|
|
@@ -77,7 +111,7 @@ from mapFolding.beDRY import (
|
|
|
77
111
|
validateListDimensions as validateListDimensions,
|
|
78
112
|
)
|
|
79
113
|
|
|
80
|
-
from mapFolding.toolboxFilesystem import (
|
|
114
|
+
from mapFolding.toolboxFilesystem import ( # noqa: E402
|
|
81
115
|
getPathFilenameFoldsTotal as getPathFilenameFoldsTotal,
|
|
82
116
|
getPathRootJobDEFAULT as getPathRootJobDEFAULT,
|
|
83
117
|
saveFoldsTotal as saveFoldsTotal,
|
|
@@ -85,9 +119,9 @@ from mapFolding.toolboxFilesystem import (
|
|
|
85
119
|
writeStringToHere as writeStringToHere,
|
|
86
120
|
)
|
|
87
121
|
|
|
88
|
-
from mapFolding.
|
|
122
|
+
from mapFolding.basecamp import countFolds as countFolds # noqa: E402
|
|
89
123
|
|
|
90
|
-
from mapFolding.oeis import (
|
|
124
|
+
from mapFolding.oeis import ( # noqa: E402
|
|
91
125
|
clearOEIScache as clearOEIScache,
|
|
92
126
|
getFoldsTotalKnown as getFoldsTotalKnown,
|
|
93
127
|
getOEISids as getOEISids,
|
mapFolding/basecamp.py
CHANGED
|
@@ -23,10 +23,15 @@ from mapFolding import (
|
|
|
23
23
|
from os import PathLike
|
|
24
24
|
from pathlib import PurePath
|
|
25
25
|
|
|
26
|
-
def countFolds(listDimensions: Sequence[int]
|
|
26
|
+
def countFolds(listDimensions: Sequence[int] | None = None
|
|
27
27
|
, pathLikeWriteFoldsTotal: PathLike[str] | PurePath | None = None
|
|
28
28
|
, computationDivisions: int | str | None = None
|
|
29
29
|
, CPUlimit: int | float | bool | None = None
|
|
30
|
+
# , * I need to improve `standardizedEqualToCallableReturn` so it will work with keyword arguments
|
|
31
|
+
, mapShape: tuple[int, ...] | None = None
|
|
32
|
+
, oeisID: str | None = None
|
|
33
|
+
, oeis_n: int | None = None
|
|
34
|
+
, flow: str | None = None
|
|
30
35
|
) -> int:
|
|
31
36
|
"""
|
|
32
37
|
Count the total number of possible foldings for a given map dimensions.
|
|
@@ -75,21 +80,107 @@ def countFolds(listDimensions: Sequence[int]
|
|
|
75
80
|
computation time. If logicalCores >= `leavesTotal`, it will probably be faster. If logicalCores <= 2 * `leavesTotal`, it
|
|
76
81
|
will almost certainly be slower for all map dimensions.
|
|
77
82
|
"""
|
|
78
|
-
mapShape
|
|
79
|
-
|
|
80
|
-
|
|
83
|
+
# mapShape =====================================================================
|
|
84
|
+
|
|
85
|
+
if mapShape:
|
|
86
|
+
pass
|
|
87
|
+
else:
|
|
88
|
+
if oeisID and oeis_n:
|
|
89
|
+
from mapFolding.oeis import settingsOEIS
|
|
90
|
+
try:
|
|
91
|
+
mapShape = settingsOEIS[oeisID]['getMapShape'](oeis_n)
|
|
92
|
+
except KeyError:
|
|
93
|
+
pass
|
|
94
|
+
if not mapShape and listDimensions:
|
|
95
|
+
mapShape = validateListDimensions(listDimensions)
|
|
96
|
+
|
|
97
|
+
if mapShape is None:
|
|
98
|
+
raise ValueError(f"""I received these values:
|
|
99
|
+
`{listDimensions = }`,
|
|
100
|
+
`{mapShape = }`,
|
|
101
|
+
`{oeisID = }` and `{oeis_n = }`,
|
|
102
|
+
but I was unable to select a map for which to count the folds.""")
|
|
103
|
+
|
|
104
|
+
# task division instructions ===============================================
|
|
105
|
+
|
|
106
|
+
if computationDivisions:
|
|
107
|
+
# NOTE `The.concurrencyPackage`
|
|
108
|
+
concurrencyLimit: int = setProcessorLimit(CPUlimit, The.concurrencyPackage)
|
|
109
|
+
from mapFolding.beDRY import getLeavesTotal, getTaskDivisions
|
|
110
|
+
leavesTotal: int = getLeavesTotal(mapShape)
|
|
111
|
+
taskDivisions = getTaskDivisions(computationDivisions, concurrencyLimit, leavesTotal)
|
|
112
|
+
del leavesTotal
|
|
113
|
+
else:
|
|
114
|
+
concurrencyLimit = 1
|
|
115
|
+
taskDivisions = 0
|
|
116
|
+
|
|
117
|
+
# memorialization instructions ===========================================
|
|
81
118
|
|
|
82
119
|
if pathLikeWriteFoldsTotal is not None:
|
|
83
|
-
pathFilenameFoldsTotal = getPathFilenameFoldsTotal(
|
|
120
|
+
pathFilenameFoldsTotal = getPathFilenameFoldsTotal(mapShape, pathLikeWriteFoldsTotal)
|
|
84
121
|
saveFoldsTotalFAILearly(pathFilenameFoldsTotal)
|
|
85
122
|
else:
|
|
86
123
|
pathFilenameFoldsTotal = None
|
|
87
124
|
|
|
88
|
-
|
|
125
|
+
# Flow control until I can figure out a good way ===============================
|
|
126
|
+
|
|
127
|
+
if flow == 'daoOfMapFolding':
|
|
128
|
+
from mapFolding.dataBaskets import MapFoldingState
|
|
129
|
+
mapFoldingState: MapFoldingState = MapFoldingState(mapShape)
|
|
130
|
+
|
|
131
|
+
from mapFolding.daoOfMapFolding import doTheNeedful
|
|
132
|
+
mapFoldingState = doTheNeedful(mapFoldingState)
|
|
133
|
+
foldsTotal = mapFoldingState.foldsTotal
|
|
134
|
+
|
|
135
|
+
elif flow == 'theorem2' and any((dimension > 2 for dimension in mapShape)):
|
|
136
|
+
from mapFolding.dataBaskets import MapFoldingState
|
|
137
|
+
mapFoldingState: MapFoldingState = MapFoldingState(mapShape)
|
|
138
|
+
|
|
139
|
+
from mapFolding.syntheticModules.initializeCount import initializeGroupsOfFolds
|
|
140
|
+
mapFoldingState = initializeGroupsOfFolds(mapFoldingState)
|
|
141
|
+
|
|
142
|
+
from mapFolding.syntheticModules.theorem2 import count
|
|
143
|
+
mapFoldingState = count(mapFoldingState)
|
|
144
|
+
|
|
145
|
+
foldsTotal = mapFoldingState.foldsTotal
|
|
146
|
+
|
|
147
|
+
elif flow == 'theorem2Trimmed' and any((dimension > 2 for dimension in mapShape)):
|
|
148
|
+
from mapFolding.dataBaskets import MapFoldingState
|
|
149
|
+
mapFoldingState: MapFoldingState = MapFoldingState(mapShape)
|
|
150
|
+
|
|
151
|
+
from mapFolding.syntheticModules.initializeCount import initializeGroupsOfFolds
|
|
152
|
+
mapFoldingState = initializeGroupsOfFolds(mapFoldingState)
|
|
153
|
+
|
|
154
|
+
from mapFolding.syntheticModules.theorem2Trimmed import count
|
|
155
|
+
mapFoldingState = count(mapFoldingState)
|
|
156
|
+
|
|
157
|
+
foldsTotal = mapFoldingState.foldsTotal
|
|
158
|
+
|
|
159
|
+
elif (flow == 'theorem2Numba' or taskDivisions == 0) and any((dimension > 2 for dimension in mapShape)):
|
|
160
|
+
from mapFolding.dataBaskets import MapFoldingState
|
|
161
|
+
mapFoldingState: MapFoldingState = MapFoldingState(mapShape)
|
|
162
|
+
|
|
163
|
+
from mapFolding.syntheticModules.initializeCount import initializeGroupsOfFolds
|
|
164
|
+
mapFoldingState = initializeGroupsOfFolds(mapFoldingState)
|
|
165
|
+
|
|
166
|
+
from mapFolding.syntheticModules.dataPacking import doTheNeedful
|
|
167
|
+
mapFoldingState = doTheNeedful(mapFoldingState)
|
|
168
|
+
|
|
169
|
+
foldsTotal = mapFoldingState.foldsTotal
|
|
170
|
+
|
|
171
|
+
# NOTE treat this as a default?
|
|
172
|
+
# flow based on `The` and `ComputationState` ====================================
|
|
173
|
+
|
|
174
|
+
else:
|
|
175
|
+
computationStateInitialized: ComputationState = outfitCountFolds(mapShape, computationDivisions, concurrencyLimit)
|
|
176
|
+
computationStateComplete: ComputationState = The.dispatcher(computationStateInitialized)
|
|
177
|
+
|
|
178
|
+
computationStateComplete.getFoldsTotal()
|
|
179
|
+
foldsTotal = computationStateComplete.foldsTotal
|
|
89
180
|
|
|
90
|
-
|
|
181
|
+
# Follow memorialization instructions ===========================================
|
|
91
182
|
|
|
92
183
|
if pathFilenameFoldsTotal is not None:
|
|
93
|
-
saveFoldsTotal(pathFilenameFoldsTotal,
|
|
184
|
+
saveFoldsTotal(pathFilenameFoldsTotal, foldsTotal)
|
|
94
185
|
|
|
95
|
-
return
|
|
186
|
+
return foldsTotal
|
mapFolding/beDRY.py
CHANGED
|
@@ -59,14 +59,12 @@ def getTaskDivisions(computationDivisions: int | str | None, concurrencyLimit: i
|
|
|
59
59
|
"""
|
|
60
60
|
Determines whether to divide the computation into tasks and how many divisions.
|
|
61
61
|
|
|
62
|
+
|
|
62
63
|
Parameters
|
|
63
64
|
----------
|
|
64
65
|
computationDivisions: None
|
|
65
|
-
Specifies how to divide computations:
|
|
66
|
-
|
|
67
|
-
- int: directly set the number of task divisions; cannot exceed the map's total leaves.
|
|
68
|
-
- `'maximum'`: divides into `leavesTotal`-many `taskDivisions`.
|
|
69
|
-
- `'cpu'`: limits the divisions to the number of available CPUs: i.e., `concurrencyLimit`.
|
|
66
|
+
Specifies how to divide computations: Please see the documentation in `countFolds` for details. I know it is
|
|
67
|
+
annoying, but I want to be sure you have the most accurate information.
|
|
70
68
|
concurrencyLimit
|
|
71
69
|
Maximum number of concurrent tasks allowed.
|
|
72
70
|
|
|
@@ -224,7 +222,7 @@ def outfitCountFolds(mapShape: tuple[int, ...], computationDivisions: int | str
|
|
|
224
222
|
A tuple of integers representing the dimensions of the map.
|
|
225
223
|
computationDivisions: None
|
|
226
224
|
Controls how to divide the computation into parallel tasks. I know it is annoying, but please see
|
|
227
|
-
`
|
|
225
|
+
`countFolds` for details, so that you and I both know you have the most accurate information.
|
|
228
226
|
concurrencyLimit: 1
|
|
229
227
|
Maximum number of concurrent processes to use during computation.
|
|
230
228
|
|
|
@@ -245,19 +243,13 @@ def outfitCountFolds(mapShape: tuple[int, ...], computationDivisions: int | str
|
|
|
245
243
|
|
|
246
244
|
def setProcessorLimit(CPUlimit: Any | None, concurrencyPackage: str | None = None) -> int:
|
|
247
245
|
"""
|
|
248
|
-
|
|
246
|
+
Whether and how to limit the CPU usage.
|
|
249
247
|
|
|
250
248
|
Parameters
|
|
251
249
|
----------
|
|
252
250
|
CPUlimit: None
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
potentially limit processor usage.
|
|
256
|
-
- `True`: Yes, limit the processor usage; limits to 1 processor.
|
|
257
|
-
- Integer `>= 1`: Limits usage to the specified number of processors.
|
|
258
|
-
- Decimal value (`float`) between 0 and 1: Fraction of total processors to use.
|
|
259
|
-
- Decimal value (`float`) between -1 and 0: Fraction of processors to _not_ use.
|
|
260
|
-
- Integer `<= -1`: Subtract the absolute value from total processors.
|
|
251
|
+
Please see the documentation for in `countFolds` for details. I know it is annoying, but I want to be sure you
|
|
252
|
+
have the most accurate information.
|
|
261
253
|
concurrencyPackage: None
|
|
262
254
|
Specifies which concurrency package to use:
|
|
263
255
|
- `None` or `'multiprocessing'`: Uses standard `multiprocessing`.
|
mapFolding/dataBaskets.py
CHANGED
|
@@ -47,3 +47,15 @@ class MapFoldingState:
|
|
|
47
47
|
if self.gapRangeStart is None: self.gapRangeStart = makeDataContainer(leavesTotalAsInt + 1, self.__dataclass_fields__['gapRangeStart'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison]
|
|
48
48
|
if self.leafAbove is None: self.leafAbove = makeDataContainer(leavesTotalAsInt + 1, self.__dataclass_fields__['leafAbove'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison]
|
|
49
49
|
if self.leafBelow is None: self.leafBelow = makeDataContainer(leavesTotalAsInt + 1, self.__dataclass_fields__['leafBelow'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison]
|
|
50
|
+
|
|
51
|
+
@dataclasses.dataclass
|
|
52
|
+
class LeafSequenceState(MapFoldingState):
|
|
53
|
+
leafSequence: Array1DLeavesTotal = dataclasses.field(default=None, init=True, metadata={'dtype': Array1DLeavesTotal.__args__[1].__args__[0]}) # pyright: ignore[reportAssignmentType, reportAttributeAccessIssue, reportUnknownMemberType]
|
|
54
|
+
|
|
55
|
+
def __post_init__(self) -> None:
|
|
56
|
+
super().__post_init__()
|
|
57
|
+
from mapFolding.oeis import getFoldsTotalKnown
|
|
58
|
+
groupsOfFoldsKnown = getFoldsTotalKnown(self.mapShape) // self.leavesTotal
|
|
59
|
+
if self.leafSequence is None: # pyright: ignore[reportUnnecessaryComparison]
|
|
60
|
+
self.leafSequence = makeDataContainer(groupsOfFoldsKnown, self.__dataclass_fields__['leafSequence'].metadata['dtype'])
|
|
61
|
+
self.leafSequence[self.groupsOfFolds] = self.leaf1ndex
|
mapFolding/datatypes.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from numpy import dtype,
|
|
1
|
+
from numpy import dtype, uint8 as numpy_uint8, uint16 as numpy_uint16, uint64 as numpy_uint64, integer, ndarray
|
|
2
2
|
from typing import Any, TypeAlias, TypeVar
|
|
3
3
|
|
|
4
4
|
# =============================================================================
|
|
@@ -7,13 +7,13 @@ from typing import Any, TypeAlias, TypeVar
|
|
|
7
7
|
NumPyIntegerType = TypeVar('NumPyIntegerType', bound=integer[Any], covariant=True)
|
|
8
8
|
|
|
9
9
|
DatatypeLeavesTotal: TypeAlias = int
|
|
10
|
-
NumPyLeavesTotal: TypeAlias =
|
|
10
|
+
NumPyLeavesTotal: TypeAlias = numpy_uint8
|
|
11
11
|
|
|
12
12
|
DatatypeElephino: TypeAlias = int
|
|
13
|
-
NumPyElephino: TypeAlias =
|
|
13
|
+
NumPyElephino: TypeAlias = numpy_uint16
|
|
14
14
|
|
|
15
15
|
DatatypeFoldsTotal: TypeAlias = int
|
|
16
|
-
NumPyFoldsTotal: TypeAlias =
|
|
16
|
+
NumPyFoldsTotal: TypeAlias = numpy_uint64
|
|
17
17
|
|
|
18
18
|
Array3D: TypeAlias = ndarray[tuple[int, int, int], dtype[NumPyLeavesTotal]]
|
|
19
19
|
Array1DLeavesTotal: TypeAlias = ndarray[tuple[int], dtype[NumPyLeavesTotal]]
|
mapFolding/oeis.py
CHANGED
|
@@ -20,9 +20,9 @@ mathematical definition in OEIS and the computational implementation in the pack
|
|
|
20
20
|
from collections.abc import Callable
|
|
21
21
|
from datetime import datetime, timedelta
|
|
22
22
|
from functools import cache
|
|
23
|
-
from mapFolding import countFolds, The, writeStringToHere
|
|
23
|
+
from mapFolding import countFolds, The, TypedDict, writeStringToHere
|
|
24
24
|
from pathlib import Path
|
|
25
|
-
from typing import Any, Final
|
|
25
|
+
from typing import Any, Final
|
|
26
26
|
import argparse
|
|
27
27
|
import random
|
|
28
28
|
import sys
|
|
@@ -31,11 +31,6 @@ import urllib.request
|
|
|
31
31
|
import urllib.response
|
|
32
32
|
import warnings
|
|
33
33
|
|
|
34
|
-
if TYPE_CHECKING:
|
|
35
|
-
from typing import TypedDict
|
|
36
|
-
else:
|
|
37
|
-
TypedDict = dict[Any, Any]
|
|
38
|
-
|
|
39
34
|
cacheDays = 30
|
|
40
35
|
|
|
41
36
|
pathCache: Path = The.pathPackage / ".cache"
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
from mapFolding.someAssemblyRequired import ShatteredDataclass, ast_Identifier, parsePathFilename2astModule, str_nameDOTname
|
|
1
|
+
from mapFolding.someAssemblyRequired import ShatteredDataclass, ast_Identifier, parseLogicalPath2astModule, parsePathFilename2astModule, str_nameDOTname
|
|
2
2
|
from mapFolding.someAssemblyRequired.toolboxNumba import theNumbaFlow
|
|
3
3
|
from mapFolding.someAssemblyRequired.transformationTools import shatter_dataclassesDOTdataclass
|
|
4
4
|
from mapFolding.theSSOT import ComputationState, DatatypeElephino as TheDatatypeElephino, DatatypeFoldsTotal as TheDatatypeFoldsTotal, DatatypeLeavesTotal as TheDatatypeLeavesTotal
|
|
5
5
|
from mapFolding.toolboxFilesystem import getPathFilenameFoldsTotal, getPathRootJobDEFAULT
|
|
6
|
-
|
|
7
|
-
import dataclasses
|
|
6
|
+
from mapFolding.dataBaskets import MapFoldingState
|
|
8
7
|
from pathlib import Path, PurePosixPath
|
|
9
8
|
from typing import TypeAlias
|
|
9
|
+
import dataclasses
|
|
10
10
|
|
|
11
11
|
@dataclasses.dataclass
|
|
12
12
|
class RecipeJob:
|
|
@@ -101,3 +101,97 @@ class RecipeJob:
|
|
|
101
101
|
dataclassInstanceTaskDistribution: ast_Identifier = sourceDataclassInstanceTaskDistribution
|
|
102
102
|
concurrencyManagerNamespace: ast_Identifier = sourceConcurrencyManagerNamespace
|
|
103
103
|
concurrencyManagerIdentifier: ast_Identifier = sourceConcurrencyManagerIdentifier
|
|
104
|
+
|
|
105
|
+
@dataclasses.dataclass
|
|
106
|
+
class RecipeJobTheorem2Numba:
|
|
107
|
+
state: MapFoldingState
|
|
108
|
+
# TODO create function to calculate `foldsTotalEstimated`
|
|
109
|
+
foldsTotalEstimated: int = 0
|
|
110
|
+
shatteredDataclass: ShatteredDataclass = dataclasses.field(default=None, init=True) # pyright: ignore[reportAssignmentType]
|
|
111
|
+
|
|
112
|
+
# ========================================
|
|
113
|
+
# Source
|
|
114
|
+
source_astModule = parseLogicalPath2astModule('mapFolding.syntheticModules.theorem2Numba')
|
|
115
|
+
sourceCountCallable: ast_Identifier = 'count'
|
|
116
|
+
|
|
117
|
+
sourceLogicalPathModuleDataclass: str_nameDOTname = 'mapFolding.dataBaskets'
|
|
118
|
+
sourceDataclassIdentifier: ast_Identifier = 'MapFoldingState'
|
|
119
|
+
sourceDataclassInstance: ast_Identifier = theNumbaFlow.dataclassInstance
|
|
120
|
+
|
|
121
|
+
sourcePathPackage: PurePosixPath | None = theNumbaFlow.pathPackage
|
|
122
|
+
sourcePackageIdentifier: ast_Identifier | None = theNumbaFlow.packageIdentifier
|
|
123
|
+
|
|
124
|
+
# ========================================
|
|
125
|
+
# Filesystem (names of physical objects)
|
|
126
|
+
pathPackage: PurePosixPath | None = None
|
|
127
|
+
pathModule: PurePosixPath | None = PurePosixPath(getPathRootJobDEFAULT())
|
|
128
|
+
""" `pathModule` will override `pathPackage` and `logicalPathRoot`."""
|
|
129
|
+
fileExtension: str = theNumbaFlow.fileExtension
|
|
130
|
+
pathFilenameFoldsTotal: PurePosixPath = dataclasses.field(default=None, init=True) # pyright: ignore[reportAssignmentType]
|
|
131
|
+
|
|
132
|
+
# ========================================
|
|
133
|
+
# Logical identifiers (as opposed to physical identifiers)
|
|
134
|
+
packageIdentifier: ast_Identifier | None = None
|
|
135
|
+
logicalPathRoot: str_nameDOTname | None = None
|
|
136
|
+
""" `logicalPathRoot` likely corresponds to a physical filesystem directory."""
|
|
137
|
+
moduleIdentifier: ast_Identifier = dataclasses.field(default=None, init=True) # pyright: ignore[reportAssignmentType]
|
|
138
|
+
countCallable: ast_Identifier = sourceCountCallable
|
|
139
|
+
dataclassIdentifier: ast_Identifier | None = sourceDataclassIdentifier
|
|
140
|
+
dataclassInstance: ast_Identifier | None = sourceDataclassInstance
|
|
141
|
+
logicalPathModuleDataclass: str_nameDOTname | None = sourceLogicalPathModuleDataclass
|
|
142
|
+
|
|
143
|
+
# ========================================
|
|
144
|
+
# Datatypes
|
|
145
|
+
DatatypeFoldsTotal: TypeAlias = TheDatatypeFoldsTotal
|
|
146
|
+
DatatypeElephino: TypeAlias = TheDatatypeElephino
|
|
147
|
+
DatatypeLeavesTotal: TypeAlias = TheDatatypeLeavesTotal
|
|
148
|
+
|
|
149
|
+
def _makePathFilename(self,
|
|
150
|
+
pathRoot: PurePosixPath | None = None,
|
|
151
|
+
logicalPathINFIX: str_nameDOTname | None = None,
|
|
152
|
+
filenameStem: str | None = None,
|
|
153
|
+
fileExtension: str | None = None,
|
|
154
|
+
) -> PurePosixPath:
|
|
155
|
+
if pathRoot is None:
|
|
156
|
+
pathRoot = self.pathPackage or PurePosixPath(Path.cwd())
|
|
157
|
+
if logicalPathINFIX:
|
|
158
|
+
whyIsThisStillAThing: list[str] = logicalPathINFIX.split('.')
|
|
159
|
+
pathRoot = pathRoot.joinpath(*whyIsThisStillAThing)
|
|
160
|
+
if filenameStem is None:
|
|
161
|
+
filenameStem = self.moduleIdentifier
|
|
162
|
+
if fileExtension is None:
|
|
163
|
+
fileExtension = self.fileExtension
|
|
164
|
+
filename: str = filenameStem + fileExtension
|
|
165
|
+
return pathRoot.joinpath(filename)
|
|
166
|
+
|
|
167
|
+
@property
|
|
168
|
+
def pathFilenameModule(self) -> PurePosixPath:
|
|
169
|
+
if self.pathModule is None:
|
|
170
|
+
return self._makePathFilename()
|
|
171
|
+
else:
|
|
172
|
+
return self._makePathFilename(pathRoot=self.pathModule, logicalPathINFIX=None)
|
|
173
|
+
|
|
174
|
+
def __post_init__(self):
|
|
175
|
+
pathFilenameFoldsTotal = PurePosixPath(getPathFilenameFoldsTotal(self.state.mapShape))
|
|
176
|
+
|
|
177
|
+
if self.moduleIdentifier is None: # pyright: ignore[reportUnnecessaryComparison]
|
|
178
|
+
self.moduleIdentifier = pathFilenameFoldsTotal.stem
|
|
179
|
+
|
|
180
|
+
if self.pathFilenameFoldsTotal is None: # pyright: ignore[reportUnnecessaryComparison]
|
|
181
|
+
self.pathFilenameFoldsTotal = pathFilenameFoldsTotal
|
|
182
|
+
|
|
183
|
+
if self.shatteredDataclass is None and self.logicalPathModuleDataclass and self.dataclassIdentifier and self.dataclassInstance: # pyright: ignore[reportUnnecessaryComparison]
|
|
184
|
+
self.shatteredDataclass = shatter_dataclassesDOTdataclass(self.logicalPathModuleDataclass, self.dataclassIdentifier, self.dataclassInstance)
|
|
185
|
+
|
|
186
|
+
# ========================================
|
|
187
|
+
# Fields you probably don't need =================================
|
|
188
|
+
# Dispatcher =================================
|
|
189
|
+
sourceDispatcherCallable: ast_Identifier = theNumbaFlow.callableDispatcher
|
|
190
|
+
dispatcherCallable: ast_Identifier = sourceDispatcherCallable
|
|
191
|
+
# Parallel counting =================================
|
|
192
|
+
sourceDataclassInstanceTaskDistribution: ast_Identifier = theNumbaFlow.dataclassInstanceTaskDistribution
|
|
193
|
+
sourceConcurrencyManagerNamespace: ast_Identifier = theNumbaFlow.concurrencyManagerNamespace
|
|
194
|
+
sourceConcurrencyManagerIdentifier: ast_Identifier = theNumbaFlow.concurrencyManagerIdentifier
|
|
195
|
+
dataclassInstanceTaskDistribution: ast_Identifier = sourceDataclassInstanceTaskDistribution
|
|
196
|
+
concurrencyManagerNamespace: ast_Identifier = sourceConcurrencyManagerNamespace
|
|
197
|
+
concurrencyManagerIdentifier: ast_Identifier = sourceConcurrencyManagerIdentifier
|
|
@@ -64,11 +64,79 @@ def makeInitializeGroupsOfFolds():
|
|
|
64
64
|
]))
|
|
65
65
|
NodeChanger(findThis, doThat).visit(countInitializeIngredients.astFunctionDef.body[0])
|
|
66
66
|
|
|
67
|
-
|
|
67
|
+
ingredientsModule = IngredientsModule(countInitializeIngredients)
|
|
68
68
|
|
|
69
69
|
pathFilename = PurePath(The.pathPackage, logicalPathInfix, moduleIdentifier + The.fileExtension)
|
|
70
70
|
|
|
71
|
-
write_astModule(
|
|
71
|
+
write_astModule(ingredientsModule, pathFilename, The.packageName)
|
|
72
|
+
|
|
73
|
+
def makeDaoOfMapFolding():
|
|
74
|
+
moduleIdentifierHARDCODED: ast_Identifier = 'daoOfMapFolding'
|
|
75
|
+
|
|
76
|
+
algorithmSourceModule = algorithmSourceModuleHARDCODED
|
|
77
|
+
sourceCallableIdentifier = sourceCallableIdentifierHARDCODED
|
|
78
|
+
logicalPathSourceModule = '.'.join([The.packageName, algorithmSourceModule])
|
|
79
|
+
|
|
80
|
+
logicalPathInfix = logicalPathInfixHARDCODED
|
|
81
|
+
moduleIdentifier = moduleIdentifierHARDCODED
|
|
82
|
+
|
|
83
|
+
astModule = parseLogicalPath2astModule(logicalPathSourceModule)
|
|
84
|
+
daoOfMapFolding = IngredientsFunction(inlineFunctionDef(sourceCallableIdentifier, astModule)
|
|
85
|
+
, LedgerOfImports(astModule))
|
|
86
|
+
|
|
87
|
+
dataclassName: ast.expr | None = NodeTourist(be.arg, Then.extractIt(DOT.annotation)).captureLastMatch(daoOfMapFolding.astFunctionDef)
|
|
88
|
+
if dataclassName is None: raise raiseIfNoneGitHubIssueNumber3
|
|
89
|
+
dataclass_Identifier: ast_Identifier | None = NodeTourist(be.Name, Then.extractIt(DOT.id)).captureLastMatch(dataclassName)
|
|
90
|
+
if dataclass_Identifier is None: raise raiseIfNoneGitHubIssueNumber3
|
|
91
|
+
|
|
92
|
+
dataclassLogicalPathModule = None
|
|
93
|
+
for moduleWithLogicalPath, listNameTuples in daoOfMapFolding.imports.dictionaryImportFrom.items():
|
|
94
|
+
for nameTuple in listNameTuples:
|
|
95
|
+
if nameTuple[0] == dataclass_Identifier:
|
|
96
|
+
dataclassLogicalPathModule = moduleWithLogicalPath
|
|
97
|
+
break
|
|
98
|
+
if dataclassLogicalPathModule:
|
|
99
|
+
break
|
|
100
|
+
if dataclassLogicalPathModule is None: raise raiseIfNoneGitHubIssueNumber3
|
|
101
|
+
dataclassInstanceIdentifier = NodeTourist(be.arg, Then.extractIt(DOT.arg)).captureLastMatch(daoOfMapFolding.astFunctionDef)
|
|
102
|
+
if dataclassInstanceIdentifier is None: raise raiseIfNoneGitHubIssueNumber3
|
|
103
|
+
shatteredDataclass = shatter_dataclassesDOTdataclass(dataclassLogicalPathModule, dataclass_Identifier, dataclassInstanceIdentifier)
|
|
104
|
+
|
|
105
|
+
# theCountingIdentifier = theCountingIdentifierHARDCODED
|
|
106
|
+
# doubleTheCount = Make.AugAssign(Make.Attribute(ast.Name(dataclassInstanceIdentifier), theCountingIdentifier), ast.Mult(), Make.Constant(2))
|
|
107
|
+
# findThis = be.Return
|
|
108
|
+
# doThat = Then.insertThisAbove([doubleTheCount])
|
|
109
|
+
# NodeChanger(findThis, doThat).visit(daoOfMapFolding.astFunctionDef)
|
|
110
|
+
|
|
111
|
+
daoOfMapFolding.imports.update(shatteredDataclass.imports)
|
|
112
|
+
daoOfMapFolding = removeDataclassFromFunction(daoOfMapFolding, shatteredDataclass)
|
|
113
|
+
|
|
114
|
+
daoOfMapFolding = removeUnusedParameters(daoOfMapFolding)
|
|
115
|
+
|
|
116
|
+
daoOfMapFolding = decorateCallableWithNumba(daoOfMapFolding, parametersNumbaLight)
|
|
117
|
+
|
|
118
|
+
sourceCallableIdentifier = The.sourceCallableDispatcher
|
|
119
|
+
|
|
120
|
+
doTheNeedful: IngredientsFunction = astModuleToIngredientsFunction(astModule, sourceCallableIdentifier)
|
|
121
|
+
doTheNeedful.imports.update(shatteredDataclass.imports)
|
|
122
|
+
targetCallableIdentifier = daoOfMapFolding.astFunctionDef.name
|
|
123
|
+
doTheNeedful = unpackDataclassCallFunctionRepackDataclass(doTheNeedful, targetCallableIdentifier, shatteredDataclass)
|
|
124
|
+
astTuple: ast.Tuple | None = NodeTourist(be.Return, Then.extractIt(DOT.value)).captureLastMatch(daoOfMapFolding.astFunctionDef)
|
|
125
|
+
if astTuple is None: raise raiseIfNoneGitHubIssueNumber3
|
|
126
|
+
astTuple.ctx = ast.Store()
|
|
127
|
+
|
|
128
|
+
findThis = ifThis.isAssignAndValueIs(ifThis.isCall_Identifier(targetCallableIdentifier))
|
|
129
|
+
doThat = Then.replaceWith(Make.Assign(listTargets=[astTuple], value=Make.Call(Make.Name(targetCallableIdentifier), astTuple.elts)))
|
|
130
|
+
NodeChanger(findThis, doThat).visit(doTheNeedful.astFunctionDef)
|
|
131
|
+
|
|
132
|
+
ingredientsModule = IngredientsModule([daoOfMapFolding, doTheNeedful])
|
|
133
|
+
ingredientsModule.removeImportFromModule('numpy')
|
|
134
|
+
|
|
135
|
+
pathFilename = PurePath(The.pathPackage, logicalPathInfix, moduleIdentifier + The.fileExtension)
|
|
136
|
+
|
|
137
|
+
write_astModule(ingredientsModule, pathFilename, The.packageName)
|
|
138
|
+
|
|
139
|
+
return pathFilename
|
|
72
140
|
|
|
73
141
|
def makeTheorem2():
|
|
74
142
|
moduleIdentifierHARDCODED: ast_Identifier = 'theorem2'
|
|
@@ -112,11 +180,42 @@ def makeTheorem2():
|
|
|
112
180
|
doThat = Then.insertThisAbove([doubleTheCount])
|
|
113
181
|
NodeChanger(findThis, doThat).visit(countTheorem2.astFunctionDef)
|
|
114
182
|
|
|
115
|
-
|
|
183
|
+
ingredientsModule = IngredientsModule(countTheorem2)
|
|
116
184
|
|
|
117
185
|
pathFilename = PurePath(The.pathPackage, logicalPathInfix, moduleIdentifier + The.fileExtension)
|
|
118
186
|
|
|
119
|
-
write_astModule(
|
|
187
|
+
write_astModule(ingredientsModule, pathFilename, The.packageName)
|
|
188
|
+
|
|
189
|
+
return pathFilename
|
|
190
|
+
|
|
191
|
+
def trimTheorem2(pathFilenameSource: PurePath):
|
|
192
|
+
logicalPathInfix = logicalPathInfixHARDCODED
|
|
193
|
+
sourceCallableIdentifier = sourceCallableIdentifierHARDCODED
|
|
194
|
+
ingredientsFunction = astModuleToIngredientsFunction(parsePathFilename2astModule(pathFilenameSource), sourceCallableIdentifier)
|
|
195
|
+
|
|
196
|
+
dataclassInstanceIdentifier = NodeTourist(be.arg, Then.extractIt(DOT.arg)).captureLastMatch(ingredientsFunction.astFunctionDef)
|
|
197
|
+
if dataclassInstanceIdentifier is None: raise raiseIfNoneGitHubIssueNumber3
|
|
198
|
+
|
|
199
|
+
findThis = ifThis.isIfUnaryNotAttributeNamespace_Identifier(dataclassInstanceIdentifier, 'dimensionsUnconstrained')
|
|
200
|
+
doThat = Then.removeIt
|
|
201
|
+
NodeChanger(findThis, doThat).visit(ingredientsFunction.astFunctionDef)
|
|
202
|
+
|
|
203
|
+
ingredientsModule = IngredientsModule(ingredientsFunction)
|
|
204
|
+
ingredientsModule.removeImportFromModule('numpy')
|
|
205
|
+
|
|
206
|
+
pathFilename = pathFilenameSource.with_stem(pathFilenameSource.stem + 'Trimmed')
|
|
207
|
+
|
|
208
|
+
write_astModule(ingredientsModule, pathFilename, The.packageName)
|
|
209
|
+
|
|
210
|
+
logicalPath: list[str] = []
|
|
211
|
+
if The.packageName:
|
|
212
|
+
logicalPath.append(The.packageName)
|
|
213
|
+
if logicalPathInfix:
|
|
214
|
+
logicalPath.append(logicalPathInfix)
|
|
215
|
+
logicalPath.append(pathFilename.stem)
|
|
216
|
+
moduleWithLogicalPath: str_nameDOTname = '.'.join(logicalPath)
|
|
217
|
+
|
|
218
|
+
astImportFrom: ast.ImportFrom = Make.ImportFrom(moduleWithLogicalPath, list_astAlias=[Make.alias(ingredientsFunction.astFunctionDef.name)])
|
|
120
219
|
|
|
121
220
|
return pathFilename
|
|
122
221
|
|
|
@@ -149,12 +248,12 @@ def numbaOnTheorem2(pathFilenameSource: PurePath):
|
|
|
149
248
|
|
|
150
249
|
countNumbaTheorem2 = decorateCallableWithNumba(countNumbaTheorem2, parametersNumbaLight)
|
|
151
250
|
|
|
152
|
-
|
|
153
|
-
|
|
251
|
+
ingredientsModule = IngredientsModule(countNumbaTheorem2)
|
|
252
|
+
ingredientsModule.removeImportFromModule('numpy')
|
|
154
253
|
|
|
155
|
-
pathFilename = pathFilenameSource.with_stem(pathFilenameSource.stem + 'Numba')
|
|
254
|
+
pathFilename = pathFilenameSource.with_stem(pathFilenameSource.stem.replace('Trimmed', '') + 'Numba')
|
|
156
255
|
|
|
157
|
-
write_astModule(
|
|
256
|
+
write_astModule(ingredientsModule, pathFilename, The.packageName)
|
|
158
257
|
|
|
159
258
|
logicalPath: list[str] = []
|
|
160
259
|
if The.packageName:
|
|
@@ -175,7 +274,6 @@ def makeUnRePackDataclass(astImportFrom: ast.ImportFrom):
|
|
|
175
274
|
sourceCallableIdentifier = The.sourceCallableDispatcher
|
|
176
275
|
logicalPathSourceModule = '.'.join([The.packageName, algorithmSourceModule])
|
|
177
276
|
|
|
178
|
-
callableIdentifier = sourceCallableIdentifier
|
|
179
277
|
logicalPathInfix = logicalPathInfixHARDCODED
|
|
180
278
|
moduleIdentifier = moduleIdentifierHARDCODED
|
|
181
279
|
|
|
@@ -212,15 +310,17 @@ def makeUnRePackDataclass(astImportFrom: ast.ImportFrom):
|
|
|
212
310
|
doThat = Then.replaceWith(Make.Assign(listTargets=[astTuple], value=Make.Call(Make.Name(targetCallableIdentifier), astTuple.elts)))
|
|
213
311
|
NodeChanger(findThis, doThat).visit(doTheNeedful.astFunctionDef)
|
|
214
312
|
|
|
215
|
-
|
|
216
|
-
|
|
313
|
+
ingredientsModule = IngredientsModule(doTheNeedful)
|
|
314
|
+
ingredientsModule.removeImportFromModule('numpy')
|
|
217
315
|
|
|
218
316
|
pathFilename = PurePath(The.pathPackage, logicalPathInfix, moduleIdentifier + The.fileExtension)
|
|
219
317
|
|
|
220
|
-
write_astModule(
|
|
318
|
+
write_astModule(ingredientsModule, pathFilename, The.packageName)
|
|
221
319
|
|
|
222
320
|
if __name__ == '__main__':
|
|
223
321
|
makeInitializeGroupsOfFolds()
|
|
224
322
|
pathFilename = makeTheorem2()
|
|
323
|
+
pathFilename = trimTheorem2(pathFilename)
|
|
225
324
|
astImportFrom = numbaOnTheorem2(pathFilename)
|
|
226
325
|
makeUnRePackDataclass(astImportFrom)
|
|
326
|
+
makeDaoOfMapFolding()
|