mapFolding 0.11.2__py3-none-any.whl → 0.11.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mapFolding/__init__.py +0 -13
- mapFolding/basecamp.py +2 -3
- mapFolding/beDRY.py +2 -145
- mapFolding/datatypes.py +0 -3
- mapFolding/oeis.py +0 -3
- mapFolding/someAssemblyRequired/RecipeJob.py +7 -114
- mapFolding/someAssemblyRequired/{Z0Z_makeSomeModules.py → Z0Z_makeAllModules.py} +33 -31
- mapFolding/someAssemblyRequired/__init__.py +4 -30
- mapFolding/someAssemblyRequired/_toolIfThis.py +1 -2
- mapFolding/someAssemblyRequired/_toolkitContainers.py +2 -122
- mapFolding/{infoBooth.py → someAssemblyRequired/infoBooth.py} +5 -31
- mapFolding/someAssemblyRequired/makeJobTheorem2Numba.py +9 -9
- mapFolding/someAssemblyRequired/toolkitNumba.py +2 -44
- mapFolding/someAssemblyRequired/transformationTools.py +7 -166
- mapFolding/theSSOT.py +9 -4
- {mapfolding-0.11.2.dist-info → mapfolding-0.11.3.dist-info}/METADATA +1 -4
- {mapfolding-0.11.2.dist-info → mapfolding-0.11.3.dist-info}/RECORD +24 -27
- {mapfolding-0.11.2.dist-info → mapfolding-0.11.3.dist-info}/WHEEL +1 -1
- tests/conftest.py +2 -77
- tests/test_computations.py +11 -18
- tests/test_tasks.py +2 -1
- mapFolding/someAssemblyRequired/synthesizeNumbaJob.py +0 -315
- mapFolding/syntheticModules/numbaCount.py +0 -202
- mapFolding/theDao.py +0 -243
- {mapfolding-0.11.2.dist-info → mapfolding-0.11.3.dist-info}/entry_points.txt +0 -0
- {mapfolding-0.11.2.dist-info → mapfolding-0.11.3.dist-info}/licenses/LICENSE +0 -0
- {mapfolding-0.11.2.dist-info → mapfolding-0.11.3.dist-info}/top_level.txt +0 -0
mapFolding/__init__.py
CHANGED
|
@@ -33,29 +33,16 @@ from mapFolding.datatypes import (
|
|
|
33
33
|
from mapFolding.theSSOT import PackageSettings as PackageSettings, packageSettings as packageSettings
|
|
34
34
|
|
|
35
35
|
from mapFolding.beDRY import (
|
|
36
|
-
ComputationState as ComputationState,
|
|
37
36
|
getConnectionGraph as getConnectionGraph,
|
|
38
37
|
getLeavesTotal as getLeavesTotal,
|
|
39
38
|
getTaskDivisions as getTaskDivisions,
|
|
40
39
|
makeDataContainer as makeDataContainer,
|
|
41
|
-
outfitCountFolds as outfitCountFolds,
|
|
42
40
|
setProcessorLimit as setProcessorLimit,
|
|
43
41
|
validateListDimensions as validateListDimensions,
|
|
44
42
|
)
|
|
45
43
|
|
|
46
44
|
from mapFolding.dataBaskets import MapFoldingState as MapFoldingState
|
|
47
45
|
|
|
48
|
-
from mapFolding.infoBooth import (
|
|
49
|
-
PackageInformation as PackageInformation,
|
|
50
|
-
raiseIfNoneGitHubIssueNumber3 as raiseIfNoneGitHubIssueNumber3,
|
|
51
|
-
The as The,
|
|
52
|
-
)
|
|
53
|
-
|
|
54
|
-
from mapFolding.theDao import (
|
|
55
|
-
countInitialize as countInitialize,
|
|
56
|
-
doTheNeedful as doTheNeedful,
|
|
57
|
-
)
|
|
58
|
-
|
|
59
46
|
from mapFolding.filesystemToolkit import (
|
|
60
47
|
getFilenameFoldsTotal as getFilenameFoldsTotal,
|
|
61
48
|
getPathFilenameFoldsTotal as getPathFilenameFoldsTotal,
|
mapFolding/basecamp.py
CHANGED
|
@@ -12,10 +12,10 @@ appropriate algorithm implementation, and optional persistence of results.
|
|
|
12
12
|
from collections.abc import Sequence
|
|
13
13
|
from mapFolding import (
|
|
14
14
|
getPathFilenameFoldsTotal,
|
|
15
|
+
packageSettings,
|
|
15
16
|
saveFoldsTotal,
|
|
16
17
|
saveFoldsTotalFAILearly,
|
|
17
18
|
setProcessorLimit,
|
|
18
|
-
The,
|
|
19
19
|
validateListDimensions,
|
|
20
20
|
)
|
|
21
21
|
from os import PathLike
|
|
@@ -102,8 +102,7 @@ def countFolds(listDimensions: Sequence[int] | None = None
|
|
|
102
102
|
# task division instructions ===============================================
|
|
103
103
|
|
|
104
104
|
if computationDivisions:
|
|
105
|
-
|
|
106
|
-
concurrencyLimit: int = setProcessorLimit(CPUlimit, The.concurrencyPackage)
|
|
105
|
+
concurrencyLimit: int = setProcessorLimit(CPUlimit, packageSettings.concurrencyPackage)
|
|
107
106
|
from mapFolding.beDRY import getLeavesTotal, getTaskDivisions
|
|
108
107
|
leavesTotal: int = getLeavesTotal(mapShape)
|
|
109
108
|
taskDivisions = getTaskDivisions(computationDivisions, concurrencyLimit, leavesTotal)
|
mapFolding/beDRY.py
CHANGED
|
@@ -208,150 +208,6 @@ def makeDataContainer(shape: int | tuple[int, ...], datatype: type[NumPyIntegerT
|
|
|
208
208
|
"""
|
|
209
209
|
return numpy.zeros(shape, dtype=datatype)
|
|
210
210
|
|
|
211
|
-
|
|
212
|
-
@dataclasses.dataclass
|
|
213
|
-
class ComputationState:
|
|
214
|
-
"""
|
|
215
|
-
Represents the complete state of a map folding computation.
|
|
216
|
-
|
|
217
|
-
This dataclass encapsulates all the information required to compute the number of possible ways to fold a map,
|
|
218
|
-
including the map dimensions, leaf connections, computation progress, and fold counting. It serves as the central
|
|
219
|
-
data structure that flows through the entire computational algorithm.
|
|
220
|
-
|
|
221
|
-
Fields are categorized into:
|
|
222
|
-
1. Input parameters (`mapShape`, `leavesTotal`, etc.).
|
|
223
|
-
2. Core computational structures (`connectionGraph`, etc.).
|
|
224
|
-
3. Tracking variables for the folding algorithm state.
|
|
225
|
-
4. Result accumulation fields (`foldsTotal`, `groupsOfFolds`).
|
|
226
|
-
"""
|
|
227
|
-
# NOTE Python is anti-DRY, again, `DatatypeLeavesTotal` metadata needs to match the type
|
|
228
|
-
mapShape: tuple[DatatypeLeavesTotal, ...] = dataclasses.field(init=True, metadata={'elementConstructor': 'DatatypeLeavesTotal'})
|
|
229
|
-
"""Dimensions of the map to be folded, as a tuple of integers."""
|
|
230
|
-
|
|
231
|
-
leavesTotal: DatatypeLeavesTotal
|
|
232
|
-
"""Total number of leaves (unit squares) in the map, equal to the product of all dimensions."""
|
|
233
|
-
|
|
234
|
-
taskDivisions: DatatypeLeavesTotal
|
|
235
|
-
"""Number of parallel tasks to divide the computation into. Zero means sequential computation."""
|
|
236
|
-
|
|
237
|
-
concurrencyLimit: DatatypeElephino
|
|
238
|
-
"""Maximum number of concurrent processes to use during computation."""
|
|
239
|
-
|
|
240
|
-
connectionGraph: Array3D = dataclasses.field(init=False, metadata={'dtype': Array3D.__args__[1].__args__[0]}) # pyright: ignore[reportUnknownMemberType, reportAttributeAccessIssue]
|
|
241
|
-
"""3D array encoding the connections between leaves in all dimensions."""
|
|
242
|
-
|
|
243
|
-
dimensionsTotal: DatatypeLeavesTotal = dataclasses.field(init=False)
|
|
244
|
-
"""Total number of dimensions in the map shape."""
|
|
245
|
-
|
|
246
|
-
# I am using `dataclasses.field` metadata and `typeAlias.__args__[1].__args__[0]` to make the code more DRY. https://github.com/hunterhogan/mapFolding/issues/9
|
|
247
|
-
countDimensionsGapped: Array1DLeavesTotal = dataclasses.field(default=None, init=True, metadata={'dtype': Array1DLeavesTotal.__args__[1].__args__[0]}) # pyright: ignore[reportAssignmentType, reportAttributeAccessIssue, reportUnknownMemberType]
|
|
248
|
-
"""Tracks how many dimensions are gapped for each leaf."""
|
|
249
|
-
|
|
250
|
-
dimensionsUnconstrained: DatatypeLeavesTotal = dataclasses.field(default=None, init=True) # pyright: ignore[reportAssignmentType, reportAttributeAccessIssue, reportUnknownMemberType]
|
|
251
|
-
"""Number of dimensions that are not constrained in the current folding state."""
|
|
252
|
-
|
|
253
|
-
gapRangeStart: Array1DElephino = dataclasses.field(default=None, init=True, metadata={'dtype': Array1DElephino.__args__[1].__args__[0]}) # pyright: ignore[reportAssignmentType, reportAttributeAccessIssue, reportUnknownMemberType]
|
|
254
|
-
"""Starting index for the gap range for each leaf."""
|
|
255
|
-
|
|
256
|
-
gapsWhere: Array1DLeavesTotal = dataclasses.field(default=None, init=True, metadata={'dtype': Array1DLeavesTotal.__args__[1].__args__[0]}) # pyright: ignore[reportAssignmentType, reportAttributeAccessIssue, reportUnknownMemberType]
|
|
257
|
-
"""Tracks where gaps occur in the folding pattern."""
|
|
258
|
-
|
|
259
|
-
leafAbove: Array1DLeavesTotal = dataclasses.field(default=None, init=True, metadata={'dtype': Array1DLeavesTotal.__args__[1].__args__[0]}) # pyright: ignore[reportAssignmentType, reportAttributeAccessIssue, reportUnknownMemberType]
|
|
260
|
-
"""For each leaf, stores the index of the leaf above it in the folding pattern."""
|
|
261
|
-
|
|
262
|
-
leafBelow: Array1DLeavesTotal = dataclasses.field(default=None, init=True, metadata={'dtype': Array1DLeavesTotal.__args__[1].__args__[0]}) # pyright: ignore[reportAssignmentType, reportAttributeAccessIssue, reportUnknownMemberType]
|
|
263
|
-
"""For each leaf, stores the index of the leaf below it in the folding pattern."""
|
|
264
|
-
|
|
265
|
-
foldGroups: Array1DFoldsTotal = dataclasses.field(default=None, init=True, metadata={'dtype': Array1DFoldsTotal.__args__[1].__args__[0]}) # pyright: ignore[reportAssignmentType, reportAttributeAccessIssue, reportUnknownMemberType]
|
|
266
|
-
"""Accumulator for fold groups across parallel tasks."""
|
|
267
|
-
|
|
268
|
-
foldsTotal: DatatypeFoldsTotal = DatatypeFoldsTotal(0)
|
|
269
|
-
"""The final computed total number of distinct folding patterns."""
|
|
270
|
-
|
|
271
|
-
gap1ndex: DatatypeElephino = DatatypeElephino(0)
|
|
272
|
-
"""Current index into gaps array during algorithm execution."""
|
|
273
|
-
|
|
274
|
-
gap1ndexCeiling: DatatypeElephino = DatatypeElephino(0)
|
|
275
|
-
"""Upper limit for gap index during the current algorithm phase."""
|
|
276
|
-
|
|
277
|
-
groupsOfFolds: DatatypeFoldsTotal = dataclasses.field(default=DatatypeFoldsTotal(0), metadata={'theCountingIdentifier': True})
|
|
278
|
-
"""Accumulator for the number of fold groups found during computation."""
|
|
279
|
-
|
|
280
|
-
indexDimension: DatatypeLeavesTotal = DatatypeLeavesTotal(0)
|
|
281
|
-
"""Current dimension being processed during algorithm execution."""
|
|
282
|
-
|
|
283
|
-
indexLeaf: DatatypeLeavesTotal = DatatypeLeavesTotal(0)
|
|
284
|
-
"""Current leaf index during iteration."""
|
|
285
|
-
|
|
286
|
-
indexMiniGap: DatatypeElephino = DatatypeElephino(0)
|
|
287
|
-
"""Index used when filtering common gaps."""
|
|
288
|
-
|
|
289
|
-
leaf1ndex: DatatypeLeavesTotal = DatatypeLeavesTotal(1)
|
|
290
|
-
"""Active leaf being processed in the folding algorithm. Starts at 1, not 0."""
|
|
291
|
-
|
|
292
|
-
leafConnectee: DatatypeLeavesTotal = DatatypeLeavesTotal(0)
|
|
293
|
-
"""Leaf that is being connected to the active leaf."""
|
|
294
|
-
|
|
295
|
-
taskIndex: DatatypeLeavesTotal = DatatypeLeavesTotal(0)
|
|
296
|
-
"""Index of the current parallel task when using task divisions."""
|
|
297
|
-
|
|
298
|
-
def __post_init__(self) -> None:
|
|
299
|
-
from mapFolding.beDRY import getConnectionGraph, makeDataContainer
|
|
300
|
-
self.dimensionsTotal = DatatypeLeavesTotal(len(self.mapShape))
|
|
301
|
-
leavesTotalAsInt = int(self.leavesTotal)
|
|
302
|
-
self.connectionGraph = getConnectionGraph(self.mapShape, leavesTotalAsInt, self.__dataclass_fields__['connectionGraph'].metadata['dtype'])
|
|
303
|
-
|
|
304
|
-
if self.dimensionsUnconstrained is None: self.dimensionsUnconstrained = DatatypeLeavesTotal(int(self.dimensionsTotal)) # pyright: ignore[reportUnnecessaryComparison]
|
|
305
|
-
|
|
306
|
-
if self.foldGroups is None: # pyright: ignore[reportUnnecessaryComparison]
|
|
307
|
-
self.foldGroups = makeDataContainer(max(2, int(self.taskDivisions) + 1), self.__dataclass_fields__['foldGroups'].metadata['dtype'])
|
|
308
|
-
self.foldGroups[-1] = self.leavesTotal
|
|
309
|
-
|
|
310
|
-
# Dataclasses, Default factories, and arguments in `ComputationState` https://github.com/hunterhogan/mapFolding/issues/12
|
|
311
|
-
if self.gapsWhere is None: self.gapsWhere = makeDataContainer(leavesTotalAsInt * leavesTotalAsInt + 1, self.__dataclass_fields__['gapsWhere'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison]
|
|
312
|
-
|
|
313
|
-
if self.countDimensionsGapped is None: self.countDimensionsGapped = makeDataContainer(leavesTotalAsInt + 1, self.__dataclass_fields__['countDimensionsGapped'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison]
|
|
314
|
-
if self.gapRangeStart is None: self.gapRangeStart = makeDataContainer(leavesTotalAsInt + 1, self.__dataclass_fields__['gapRangeStart'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison]
|
|
315
|
-
if self.leafAbove is None: self.leafAbove = makeDataContainer(leavesTotalAsInt + 1, self.__dataclass_fields__['leafAbove'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison]
|
|
316
|
-
if self.leafBelow is None: self.leafBelow = makeDataContainer(leavesTotalAsInt + 1, self.__dataclass_fields__['leafBelow'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison]
|
|
317
|
-
|
|
318
|
-
# Automatic, or not, calculation in dataclass `ComputationState` https://github.com/hunterhogan/mapFolding/issues/14
|
|
319
|
-
def getFoldsTotal(self) -> None:
|
|
320
|
-
self.foldsTotal = DatatypeFoldsTotal(self.foldGroups[0:-1].sum() * self.leavesTotal)
|
|
321
|
-
|
|
322
|
-
def outfitCountFolds(mapShape: tuple[int, ...], computationDivisions: int | str | None = None, concurrencyLimit: int = 1) -> ComputationState:
|
|
323
|
-
"""
|
|
324
|
-
Initialize a `ComputationState` with validated parameters for map folding calculation.
|
|
325
|
-
|
|
326
|
-
This function serves as the central initialization point for creating a properly configured `ComputationState`
|
|
327
|
-
object, ensuring consistent calculation of the fundamental parameters (`leavesTotal` and `taskDivisions`) across the
|
|
328
|
-
entire package.
|
|
329
|
-
|
|
330
|
-
Parameters
|
|
331
|
-
----------
|
|
332
|
-
mapShape
|
|
333
|
-
A tuple of integers representing the dimensions of the map.
|
|
334
|
-
computationDivisions: None
|
|
335
|
-
Controls how to divide the computation into parallel tasks. I know it is annoying, but please see
|
|
336
|
-
`countFolds` for details, so that you and I both know you have the most accurate information.
|
|
337
|
-
concurrencyLimit: 1
|
|
338
|
-
Maximum number of concurrent processes to use during computation.
|
|
339
|
-
|
|
340
|
-
Returns
|
|
341
|
-
-------
|
|
342
|
-
computationStateInitialized
|
|
343
|
-
A fully initialized `ComputationState` object that's ready for computation.
|
|
344
|
-
|
|
345
|
-
Notes
|
|
346
|
-
-----
|
|
347
|
-
This function maintains the Single Source of Truth principle for `leavesTotal` and `taskDivisions` calculation,
|
|
348
|
-
ensuring these values are derived consistently throughout the package.
|
|
349
|
-
"""
|
|
350
|
-
leavesTotal = getLeavesTotal(mapShape)
|
|
351
|
-
taskDivisions = getTaskDivisions(computationDivisions, concurrencyLimit, leavesTotal)
|
|
352
|
-
computationStateInitialized = ComputationState(mapShape, leavesTotal, taskDivisions, concurrencyLimit)
|
|
353
|
-
return computationStateInitialized
|
|
354
|
-
|
|
355
211
|
def setProcessorLimit(CPUlimit: Any | None, concurrencyPackage: str | None = None) -> int:
|
|
356
212
|
"""
|
|
357
213
|
Whether and how to limit the CPU usage.
|
|
@@ -392,7 +248,8 @@ def setProcessorLimit(CPUlimit: Any | None, concurrencyPackage: str | None = Non
|
|
|
392
248
|
|
|
393
249
|
match concurrencyPackage:
|
|
394
250
|
case 'multiprocessing' | None:
|
|
395
|
-
# When to use multiprocessing.set_start_method
|
|
251
|
+
# When to use multiprocessing.set_start_method
|
|
252
|
+
# https://github.com/hunterhogan/mapFolding/issues/6
|
|
396
253
|
concurrencyLimit: int = defineConcurrencyLimit(CPUlimit)
|
|
397
254
|
case 'numba':
|
|
398
255
|
from numba import get_num_threads, set_num_threads
|
mapFolding/datatypes.py
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
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
|
-
# =============================================================================
|
|
5
|
-
# Flexible Data Structure System Needs Enhanced Paradigm https://github.com/hunterhogan/mapFolding/issues/9
|
|
6
|
-
|
|
7
4
|
NumPyIntegerType = TypeVar('NumPyIntegerType', bound=integer[Any], covariant=True)
|
|
8
5
|
|
|
9
6
|
DatatypeLeavesTotal: TypeAlias = int
|
mapFolding/oeis.py
CHANGED
|
@@ -144,9 +144,6 @@ def _parseBFileOEIS(OEISbFile: str, oeisID: str) -> dict[int, int]:
|
|
|
144
144
|
invalid.
|
|
145
145
|
"""
|
|
146
146
|
bFileLines: list[str] = OEISbFile.strip().splitlines()
|
|
147
|
-
# if not bFileLines.pop(0).startswith(f"# {oeisID}"):
|
|
148
|
-
# warnings.warn(f"Content does not match sequence {oeisID}")
|
|
149
|
-
# return {-1: -1}
|
|
150
147
|
|
|
151
148
|
OEISsequence: dict[int, int] = {}
|
|
152
149
|
for line in bFileLines:
|
|
@@ -1,106 +1,12 @@
|
|
|
1
|
-
from
|
|
1
|
+
from astToolkit import ast_Identifier, parseLogicalPath2astModule, str_nameDOTname
|
|
2
|
+
from mapFolding import getPathFilenameFoldsTotal, getPathRootJobDEFAULT, MapFoldingState
|
|
2
3
|
from mapFolding import DatatypeElephino as TheDatatypeElephino, DatatypeFoldsTotal as TheDatatypeFoldsTotal, DatatypeLeavesTotal as TheDatatypeLeavesTotal
|
|
3
|
-
from mapFolding.someAssemblyRequired import ShatteredDataclass,
|
|
4
|
-
from mapFolding.someAssemblyRequired.toolkitNumba import theNumbaFlow
|
|
4
|
+
from mapFolding.someAssemblyRequired import ShatteredDataclass, packageInformation
|
|
5
5
|
from mapFolding.someAssemblyRequired.transformationTools import shatter_dataclassesDOTdataclass
|
|
6
6
|
from pathlib import Path, PurePosixPath
|
|
7
7
|
from typing import TypeAlias
|
|
8
8
|
import dataclasses
|
|
9
9
|
|
|
10
|
-
@dataclasses.dataclass
|
|
11
|
-
class RecipeJob:
|
|
12
|
-
state: ComputationState
|
|
13
|
-
# TODO create function to calculate `foldsTotalEstimated`
|
|
14
|
-
foldsTotalEstimated: int = 0
|
|
15
|
-
shatteredDataclass: ShatteredDataclass = dataclasses.field(default=None, init=True) # pyright: ignore[reportAssignmentType]
|
|
16
|
-
|
|
17
|
-
# ========================================
|
|
18
|
-
# Source
|
|
19
|
-
source_astModule = parsePathFilename2astModule(theNumbaFlow.pathFilenameSequential)
|
|
20
|
-
sourceCountCallable: ast_Identifier = theNumbaFlow.callableSequential
|
|
21
|
-
|
|
22
|
-
sourceLogicalPathModuleDataclass: str_nameDOTname = theNumbaFlow.logicalPathModuleDataclass
|
|
23
|
-
sourceDataclassIdentifier: ast_Identifier = theNumbaFlow.dataclassIdentifier
|
|
24
|
-
sourceDataclassInstance: ast_Identifier = theNumbaFlow.dataclassInstance
|
|
25
|
-
|
|
26
|
-
sourcePathPackage: PurePosixPath | None = theNumbaFlow.pathPackage
|
|
27
|
-
sourcePackageIdentifier: ast_Identifier | None = theNumbaFlow.packageIdentifier
|
|
28
|
-
|
|
29
|
-
# ========================================
|
|
30
|
-
# Filesystem (names of physical objects)
|
|
31
|
-
pathPackage: PurePosixPath | None = None
|
|
32
|
-
pathModule: PurePosixPath | None = PurePosixPath(getPathRootJobDEFAULT())
|
|
33
|
-
""" `pathModule` will override `pathPackage` and `logicalPathRoot`."""
|
|
34
|
-
fileExtension: str = theNumbaFlow.fileExtension
|
|
35
|
-
pathFilenameFoldsTotal: PurePosixPath = dataclasses.field(default=None, init=True) # pyright: ignore[reportAssignmentType]
|
|
36
|
-
|
|
37
|
-
# ========================================
|
|
38
|
-
# Logical identifiers (as opposed to physical identifiers)
|
|
39
|
-
packageIdentifier: ast_Identifier | None = None
|
|
40
|
-
logicalPathRoot: str_nameDOTname | None = None
|
|
41
|
-
""" `logicalPathRoot` likely corresponds to a physical filesystem directory."""
|
|
42
|
-
moduleIdentifier: ast_Identifier = dataclasses.field(default=None, init=True) # pyright: ignore[reportAssignmentType]
|
|
43
|
-
countCallable: ast_Identifier = sourceCountCallable
|
|
44
|
-
dataclassIdentifier: ast_Identifier | None = sourceDataclassIdentifier
|
|
45
|
-
dataclassInstance: ast_Identifier | None = sourceDataclassInstance
|
|
46
|
-
logicalPathModuleDataclass: str_nameDOTname | None = sourceLogicalPathModuleDataclass
|
|
47
|
-
|
|
48
|
-
# ========================================
|
|
49
|
-
# Datatypes
|
|
50
|
-
DatatypeFoldsTotal: TypeAlias = TheDatatypeFoldsTotal
|
|
51
|
-
DatatypeElephino: TypeAlias = TheDatatypeElephino
|
|
52
|
-
DatatypeLeavesTotal: TypeAlias = TheDatatypeLeavesTotal
|
|
53
|
-
|
|
54
|
-
def _makePathFilename(self,
|
|
55
|
-
pathRoot: PurePosixPath | None = None,
|
|
56
|
-
logicalPathINFIX: str_nameDOTname | None = None,
|
|
57
|
-
filenameStem: str | None = None,
|
|
58
|
-
fileExtension: str | None = None,
|
|
59
|
-
) -> PurePosixPath:
|
|
60
|
-
if pathRoot is None:
|
|
61
|
-
pathRoot = self.pathPackage or PurePosixPath(Path.cwd())
|
|
62
|
-
if logicalPathINFIX:
|
|
63
|
-
whyIsThisStillAThing: list[str] = logicalPathINFIX.split('.')
|
|
64
|
-
pathRoot = pathRoot.joinpath(*whyIsThisStillAThing)
|
|
65
|
-
if filenameStem is None:
|
|
66
|
-
filenameStem = self.moduleIdentifier
|
|
67
|
-
if fileExtension is None:
|
|
68
|
-
fileExtension = self.fileExtension
|
|
69
|
-
filename: str = filenameStem + fileExtension
|
|
70
|
-
return pathRoot.joinpath(filename)
|
|
71
|
-
|
|
72
|
-
@property
|
|
73
|
-
def pathFilenameModule(self) -> PurePosixPath:
|
|
74
|
-
if self.pathModule is None:
|
|
75
|
-
return self._makePathFilename()
|
|
76
|
-
else:
|
|
77
|
-
return self._makePathFilename(pathRoot=self.pathModule, logicalPathINFIX=None)
|
|
78
|
-
|
|
79
|
-
def __post_init__(self):
|
|
80
|
-
pathFilenameFoldsTotal = PurePosixPath(getPathFilenameFoldsTotal(self.state.mapShape))
|
|
81
|
-
|
|
82
|
-
if self.moduleIdentifier is None: # pyright: ignore[reportUnnecessaryComparison]
|
|
83
|
-
self.moduleIdentifier = pathFilenameFoldsTotal.stem
|
|
84
|
-
|
|
85
|
-
if self.pathFilenameFoldsTotal is None: # pyright: ignore[reportUnnecessaryComparison]
|
|
86
|
-
self.pathFilenameFoldsTotal = pathFilenameFoldsTotal
|
|
87
|
-
|
|
88
|
-
if self.shatteredDataclass is None and self.logicalPathModuleDataclass and self.dataclassIdentifier and self.dataclassInstance: # pyright: ignore[reportUnnecessaryComparison]
|
|
89
|
-
self.shatteredDataclass = shatter_dataclassesDOTdataclass(self.logicalPathModuleDataclass, self.dataclassIdentifier, self.dataclassInstance)
|
|
90
|
-
|
|
91
|
-
# ========================================
|
|
92
|
-
# Fields you probably don't need =================================
|
|
93
|
-
# Dispatcher =================================
|
|
94
|
-
sourceDispatcherCallable: ast_Identifier = theNumbaFlow.callableDispatcher
|
|
95
|
-
dispatcherCallable: ast_Identifier = sourceDispatcherCallable
|
|
96
|
-
# Parallel counting =================================
|
|
97
|
-
sourceDataclassInstanceTaskDistribution: ast_Identifier = theNumbaFlow.dataclassInstanceTaskDistribution
|
|
98
|
-
sourceConcurrencyManagerNamespace: ast_Identifier = theNumbaFlow.concurrencyManagerNamespace
|
|
99
|
-
sourceConcurrencyManagerIdentifier: ast_Identifier = theNumbaFlow.concurrencyManagerIdentifier
|
|
100
|
-
dataclassInstanceTaskDistribution: ast_Identifier = sourceDataclassInstanceTaskDistribution
|
|
101
|
-
concurrencyManagerNamespace: ast_Identifier = sourceConcurrencyManagerNamespace
|
|
102
|
-
concurrencyManagerIdentifier: ast_Identifier = sourceConcurrencyManagerIdentifier
|
|
103
|
-
|
|
104
10
|
@dataclasses.dataclass
|
|
105
11
|
class RecipeJobTheorem2Numba:
|
|
106
12
|
state: MapFoldingState
|
|
@@ -115,17 +21,17 @@ class RecipeJobTheorem2Numba:
|
|
|
115
21
|
|
|
116
22
|
sourceLogicalPathModuleDataclass: str_nameDOTname = 'mapFolding.dataBaskets'
|
|
117
23
|
sourceDataclassIdentifier: ast_Identifier = 'MapFoldingState'
|
|
118
|
-
sourceDataclassInstance: ast_Identifier =
|
|
24
|
+
sourceDataclassInstance: ast_Identifier = packageInformation.dataclassInstance
|
|
119
25
|
|
|
120
|
-
sourcePathPackage: PurePosixPath | None =
|
|
121
|
-
sourcePackageIdentifier: ast_Identifier | None =
|
|
26
|
+
sourcePathPackage: PurePosixPath | None = PurePosixPath(packageInformation.pathPackage)
|
|
27
|
+
sourcePackageIdentifier: ast_Identifier | None = packageInformation.packageName
|
|
122
28
|
|
|
123
29
|
# ========================================
|
|
124
30
|
# Filesystem (names of physical objects)
|
|
125
31
|
pathPackage: PurePosixPath | None = None
|
|
126
32
|
pathModule: PurePosixPath | None = PurePosixPath(getPathRootJobDEFAULT())
|
|
127
33
|
""" `pathModule` will override `pathPackage` and `logicalPathRoot`."""
|
|
128
|
-
fileExtension: str =
|
|
34
|
+
fileExtension: str = packageInformation.fileExtension
|
|
129
35
|
pathFilenameFoldsTotal: PurePosixPath = dataclasses.field(default=None, init=True) # pyright: ignore[reportAssignmentType]
|
|
130
36
|
|
|
131
37
|
# ========================================
|
|
@@ -181,16 +87,3 @@ class RecipeJobTheorem2Numba:
|
|
|
181
87
|
|
|
182
88
|
if self.shatteredDataclass is None and self.logicalPathModuleDataclass and self.dataclassIdentifier and self.dataclassInstance: # pyright: ignore[reportUnnecessaryComparison]
|
|
183
89
|
self.shatteredDataclass = shatter_dataclassesDOTdataclass(self.logicalPathModuleDataclass, self.dataclassIdentifier, self.dataclassInstance)
|
|
184
|
-
|
|
185
|
-
# ========================================
|
|
186
|
-
# Fields you probably don't need =================================
|
|
187
|
-
# Dispatcher =================================
|
|
188
|
-
sourceDispatcherCallable: ast_Identifier = theNumbaFlow.callableDispatcher
|
|
189
|
-
dispatcherCallable: ast_Identifier = sourceDispatcherCallable
|
|
190
|
-
# Parallel counting =================================
|
|
191
|
-
sourceDataclassInstanceTaskDistribution: ast_Identifier = theNumbaFlow.dataclassInstanceTaskDistribution
|
|
192
|
-
sourceConcurrencyManagerNamespace: ast_Identifier = theNumbaFlow.concurrencyManagerNamespace
|
|
193
|
-
sourceConcurrencyManagerIdentifier: ast_Identifier = theNumbaFlow.concurrencyManagerIdentifier
|
|
194
|
-
dataclassInstanceTaskDistribution: ast_Identifier = sourceDataclassInstanceTaskDistribution
|
|
195
|
-
concurrencyManagerNamespace: ast_Identifier = sourceConcurrencyManagerNamespace
|
|
196
|
-
concurrencyManagerIdentifier: ast_Identifier = sourceConcurrencyManagerIdentifier
|
|
@@ -1,28 +1,30 @@
|
|
|
1
1
|
from collections.abc import Sequence
|
|
2
|
-
from astToolkit import
|
|
3
|
-
from mapFolding import raiseIfNoneGitHubIssueNumber3, The
|
|
4
|
-
from mapFolding.someAssemblyRequired import (
|
|
2
|
+
from astToolkit import (
|
|
5
3
|
ast_Identifier,
|
|
6
4
|
astModuleToIngredientsFunction,
|
|
7
5
|
Be,
|
|
6
|
+
ClassIsAndAttribute,
|
|
8
7
|
DOT,
|
|
8
|
+
extractClassDef,
|
|
9
9
|
extractFunctionDef,
|
|
10
10
|
Grab,
|
|
11
|
-
IfThis,
|
|
12
11
|
IngredientsFunction,
|
|
13
12
|
IngredientsModule,
|
|
14
|
-
inlineFunctionDef,
|
|
15
13
|
LedgerOfImports,
|
|
16
14
|
Make,
|
|
17
15
|
NodeChanger,
|
|
18
16
|
NodeTourist,
|
|
19
17
|
parseLogicalPath2astModule,
|
|
20
18
|
parsePathFilename2astModule,
|
|
21
|
-
removeUnusedParameters,
|
|
22
19
|
str_nameDOTname,
|
|
23
20
|
Then,
|
|
24
|
-
|
|
21
|
+
)
|
|
22
|
+
from astToolkit.transformationTools import inlineFunctionDef, removeUnusedParameters, write_astModule
|
|
23
|
+
from mapFolding.someAssemblyRequired import (
|
|
25
24
|
DeReConstructField2ast,
|
|
25
|
+
IfThis,
|
|
26
|
+
packageInformation,
|
|
27
|
+
raiseIfNoneGitHubIssueNumber3,
|
|
26
28
|
ShatteredDataclass,
|
|
27
29
|
)
|
|
28
30
|
from mapFolding.someAssemblyRequired.toolkitNumba import decorateCallableWithNumba, parametersNumbaLight
|
|
@@ -48,7 +50,7 @@ def makeInitializeGroupsOfFolds() -> None:
|
|
|
48
50
|
|
|
49
51
|
algorithmSourceModule = algorithmSourceModuleHARDCODED
|
|
50
52
|
sourceCallableIdentifier = sourceCallableIdentifierHARDCODED
|
|
51
|
-
logicalPathSourceModule = '.'.join([
|
|
53
|
+
logicalPathSourceModule = '.'.join([packageInformation.packageName, algorithmSourceModule])
|
|
52
54
|
|
|
53
55
|
callableIdentifier = callableIdentifierHARDCODED
|
|
54
56
|
logicalPathInfix = logicalPathInfixHARDCODED
|
|
@@ -70,16 +72,16 @@ def makeInitializeGroupsOfFolds() -> None:
|
|
|
70
72
|
|
|
71
73
|
ingredientsModule = IngredientsModule(countInitializeIngredients)
|
|
72
74
|
|
|
73
|
-
pathFilename = PurePath(
|
|
75
|
+
pathFilename = PurePath(packageInformation.pathPackage, logicalPathInfix, moduleIdentifier + packageInformation.fileExtension)
|
|
74
76
|
|
|
75
|
-
write_astModule(ingredientsModule, pathFilename,
|
|
77
|
+
write_astModule(ingredientsModule, pathFilename, packageInformation.packageName)
|
|
76
78
|
|
|
77
79
|
def makeDaoOfMapFolding() -> PurePath:
|
|
78
80
|
moduleIdentifierHARDCODED: ast_Identifier = 'daoOfMapFolding'
|
|
79
81
|
|
|
80
82
|
algorithmSourceModule = algorithmSourceModuleHARDCODED
|
|
81
83
|
sourceCallableIdentifier = sourceCallableIdentifierHARDCODED
|
|
82
|
-
logicalPathSourceModule = '.'.join([
|
|
84
|
+
logicalPathSourceModule = '.'.join([packageInformation.packageName, algorithmSourceModule])
|
|
83
85
|
|
|
84
86
|
logicalPathInfix = logicalPathInfixHARDCODED
|
|
85
87
|
moduleIdentifier = moduleIdentifierHARDCODED
|
|
@@ -119,7 +121,7 @@ def makeDaoOfMapFolding() -> PurePath:
|
|
|
119
121
|
|
|
120
122
|
daoOfMapFolding = decorateCallableWithNumba(daoOfMapFolding, parametersNumbaLight)
|
|
121
123
|
|
|
122
|
-
sourceCallableIdentifier =
|
|
124
|
+
sourceCallableIdentifier = packageInformation.sourceCallableDispatcher
|
|
123
125
|
|
|
124
126
|
doTheNeedful: IngredientsFunction = astModuleToIngredientsFunction(astModule, sourceCallableIdentifier)
|
|
125
127
|
doTheNeedful.imports.update(shatteredDataclass.imports)
|
|
@@ -138,9 +140,9 @@ def makeDaoOfMapFolding() -> PurePath:
|
|
|
138
140
|
ingredientsModule = IngredientsModule([daoOfMapFolding, doTheNeedful])
|
|
139
141
|
ingredientsModule.removeImportFromModule('numpy')
|
|
140
142
|
|
|
141
|
-
pathFilename = PurePath(
|
|
143
|
+
pathFilename = PurePath(packageInformation.pathPackage, logicalPathInfix, moduleIdentifier + packageInformation.fileExtension)
|
|
142
144
|
|
|
143
|
-
write_astModule(ingredientsModule, pathFilename,
|
|
145
|
+
write_astModule(ingredientsModule, pathFilename, packageInformation.packageName)
|
|
144
146
|
|
|
145
147
|
return pathFilename
|
|
146
148
|
|
|
@@ -149,7 +151,7 @@ def makeDaoOfMapFoldingParallel() -> PurePath:
|
|
|
149
151
|
|
|
150
152
|
algorithmSourceModule = algorithmSourceModuleHARDCODED
|
|
151
153
|
sourceCallableIdentifier = sourceCallableIdentifierHARDCODED
|
|
152
|
-
logicalPathSourceModule = '.'.join([
|
|
154
|
+
logicalPathSourceModule = '.'.join([packageInformation.packageName, algorithmSourceModule])
|
|
153
155
|
|
|
154
156
|
logicalPathInfix = logicalPathInfixHARDCODED
|
|
155
157
|
moduleIdentifier = moduleIdentifierHARDCODED
|
|
@@ -242,7 +244,7 @@ def makeDaoOfMapFoldingParallel() -> PurePath:
|
|
|
242
244
|
ingredientsFunction = decorateCallableWithNumba(ingredientsFunction, parametersNumbaLight)
|
|
243
245
|
|
|
244
246
|
# Start unpack/repack the dataclass function ================================================
|
|
245
|
-
sourceCallableIdentifier =
|
|
247
|
+
sourceCallableIdentifier = packageInformation.sourceCallableDispatcher
|
|
246
248
|
|
|
247
249
|
unRepackDataclass: IngredientsFunction = astModuleToIngredientsFunction(astModule, sourceCallableIdentifier)
|
|
248
250
|
unRepackDataclass.astFunctionDef.name = 'unRepack' + dataclass_IdentifierParallel
|
|
@@ -293,9 +295,9 @@ def makeDaoOfMapFoldingParallel() -> PurePath:
|
|
|
293
295
|
)
|
|
294
296
|
ingredientsModule.removeImportFromModule('numpy')
|
|
295
297
|
|
|
296
|
-
pathFilename = PurePath(
|
|
298
|
+
pathFilename = PurePath(packageInformation.pathPackage, logicalPathInfix, moduleIdentifier + packageInformation.fileExtension)
|
|
297
299
|
|
|
298
|
-
write_astModule(ingredientsModule, pathFilename,
|
|
300
|
+
write_astModule(ingredientsModule, pathFilename, packageInformation.packageName)
|
|
299
301
|
return pathFilename
|
|
300
302
|
|
|
301
303
|
def makeTheorem2() -> PurePath:
|
|
@@ -303,7 +305,7 @@ def makeTheorem2() -> PurePath:
|
|
|
303
305
|
|
|
304
306
|
algorithmSourceModule = algorithmSourceModuleHARDCODED
|
|
305
307
|
sourceCallableIdentifier = sourceCallableIdentifierHARDCODED
|
|
306
|
-
logicalPathSourceModule = '.'.join([
|
|
308
|
+
logicalPathSourceModule = '.'.join([packageInformation.packageName, algorithmSourceModule])
|
|
307
309
|
|
|
308
310
|
logicalPathInfix = logicalPathInfixHARDCODED
|
|
309
311
|
moduleIdentifier = moduleIdentifierHARDCODED
|
|
@@ -342,9 +344,9 @@ def makeTheorem2() -> PurePath:
|
|
|
342
344
|
|
|
343
345
|
ingredientsModule = IngredientsModule(countTheorem2)
|
|
344
346
|
|
|
345
|
-
pathFilename = PurePath(
|
|
347
|
+
pathFilename = PurePath(packageInformation.pathPackage, logicalPathInfix, moduleIdentifier + packageInformation.fileExtension)
|
|
346
348
|
|
|
347
|
-
write_astModule(ingredientsModule, pathFilename,
|
|
349
|
+
write_astModule(ingredientsModule, pathFilename, packageInformation.packageName)
|
|
348
350
|
|
|
349
351
|
return pathFilename
|
|
350
352
|
|
|
@@ -365,11 +367,11 @@ def trimTheorem2(pathFilenameSource: PurePath) -> PurePath:
|
|
|
365
367
|
|
|
366
368
|
pathFilename = pathFilenameSource.with_stem(pathFilenameSource.stem + 'Trimmed')
|
|
367
369
|
|
|
368
|
-
write_astModule(ingredientsModule, pathFilename,
|
|
370
|
+
write_astModule(ingredientsModule, pathFilename, packageInformation.packageName)
|
|
369
371
|
|
|
370
372
|
logicalPath: list[str] = []
|
|
371
|
-
if
|
|
372
|
-
logicalPath.append(
|
|
373
|
+
if packageInformation.packageName:
|
|
374
|
+
logicalPath.append(packageInformation.packageName)
|
|
373
375
|
if logicalPathInfix:
|
|
374
376
|
logicalPath.append(logicalPathInfix)
|
|
375
377
|
logicalPath.append(pathFilename.stem)
|
|
@@ -413,11 +415,11 @@ def numbaOnTheorem2(pathFilenameSource: PurePath) -> ast.ImportFrom:
|
|
|
413
415
|
|
|
414
416
|
pathFilename = pathFilenameSource.with_stem(pathFilenameSource.stem.replace('Trimmed', '') + 'Numba')
|
|
415
417
|
|
|
416
|
-
write_astModule(ingredientsModule, pathFilename,
|
|
418
|
+
write_astModule(ingredientsModule, pathFilename, packageInformation.packageName)
|
|
417
419
|
|
|
418
420
|
logicalPath: list[str] = []
|
|
419
|
-
if
|
|
420
|
-
logicalPath.append(
|
|
421
|
+
if packageInformation.packageName:
|
|
422
|
+
logicalPath.append(packageInformation.packageName)
|
|
421
423
|
if logicalPathInfix:
|
|
422
424
|
logicalPath.append(logicalPathInfix)
|
|
423
425
|
logicalPath.append(pathFilename.stem)
|
|
@@ -431,8 +433,8 @@ def makeUnRePackDataclass(astImportFrom: ast.ImportFrom) -> None:
|
|
|
431
433
|
callableIdentifierHARDCODED: ast_Identifier = 'sequential'
|
|
432
434
|
|
|
433
435
|
algorithmSourceModule = algorithmSourceModuleHARDCODED
|
|
434
|
-
sourceCallableIdentifier =
|
|
435
|
-
logicalPathSourceModule = '.'.join([
|
|
436
|
+
sourceCallableIdentifier = packageInformation.sourceCallableDispatcher
|
|
437
|
+
logicalPathSourceModule = '.'.join([packageInformation.packageName, algorithmSourceModule])
|
|
436
438
|
|
|
437
439
|
logicalPathInfix = logicalPathInfixHARDCODED
|
|
438
440
|
moduleIdentifier = dataPackingModuleIdentifierHARDCODED
|
|
@@ -476,9 +478,9 @@ def makeUnRePackDataclass(astImportFrom: ast.ImportFrom) -> None:
|
|
|
476
478
|
ingredientsModule = IngredientsModule(ingredientsFunction)
|
|
477
479
|
ingredientsModule.removeImportFromModule('numpy')
|
|
478
480
|
|
|
479
|
-
pathFilename = PurePath(
|
|
481
|
+
pathFilename = PurePath(packageInformation.pathPackage, logicalPathInfix, moduleIdentifier + packageInformation.fileExtension)
|
|
480
482
|
|
|
481
|
-
write_astModule(ingredientsModule, pathFilename,
|
|
483
|
+
write_astModule(ingredientsModule, pathFilename, packageInformation.packageName)
|
|
482
484
|
|
|
483
485
|
if __name__ == '__main__':
|
|
484
486
|
makeInitializeGroupsOfFolds()
|
|
@@ -44,41 +44,15 @@ optimizations - while maintaining the ability to verify correctness at each tran
|
|
|
44
44
|
test suite.
|
|
45
45
|
"""
|
|
46
46
|
|
|
47
|
-
from
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
Be as Be,
|
|
52
|
-
DOT as DOT,
|
|
53
|
-
extractClassDef as extractClassDef,
|
|
54
|
-
extractFunctionDef as extractFunctionDef,
|
|
55
|
-
Grab as Grab,
|
|
56
|
-
IngredientsFunction as IngredientsFunction,
|
|
57
|
-
IngredientsModule as IngredientsModule,
|
|
58
|
-
LedgerOfImports as LedgerOfImports,
|
|
59
|
-
Make as Make,
|
|
60
|
-
NodeChanger as NodeChanger,
|
|
61
|
-
NodeORattribute as NodeORattribute,
|
|
62
|
-
NodeTourist as NodeTourist,
|
|
63
|
-
parseLogicalPath2astModule as parseLogicalPath2astModule,
|
|
64
|
-
parsePathFilename2astModule as parsePathFilename2astModule,
|
|
65
|
-
str_nameDOTname as str_nameDOTname,
|
|
66
|
-
Then as Then,
|
|
67
|
-
)
|
|
68
|
-
|
|
69
|
-
from Z0Z_tools import importLogicalPath2Callable as importLogicalPath2Callable, importPathFilename2Callable as importPathFilename2Callable
|
|
70
|
-
|
|
71
|
-
from astToolkit.transformationTools import (
|
|
72
|
-
inlineFunctionDef as inlineFunctionDef,
|
|
73
|
-
removeUnusedParameters as removeUnusedParameters,
|
|
74
|
-
unparseFindReplace as unparseFindReplace,
|
|
75
|
-
write_astModule as write_astModule,
|
|
47
|
+
from mapFolding.someAssemblyRequired.infoBooth import (
|
|
48
|
+
PackageInformation as PackageInformation,
|
|
49
|
+
raiseIfNoneGitHubIssueNumber3 as raiseIfNoneGitHubIssueNumber3,
|
|
50
|
+
packageInformation as packageInformation,
|
|
76
51
|
)
|
|
77
52
|
|
|
78
53
|
from mapFolding.someAssemblyRequired._toolIfThis import IfThis as IfThis
|
|
79
54
|
|
|
80
55
|
from mapFolding.someAssemblyRequired._toolkitContainers import (
|
|
81
56
|
DeReConstructField2ast as DeReConstructField2ast,
|
|
82
|
-
RecipeSynthesizeFlow as RecipeSynthesizeFlow,
|
|
83
57
|
ShatteredDataclass as ShatteredDataclass,
|
|
84
58
|
)
|
|
@@ -19,9 +19,8 @@ they implement a declarative approach to AST manipulation that separates node id
|
|
|
19
19
|
(be), and data access (DOT).
|
|
20
20
|
"""
|
|
21
21
|
|
|
22
|
-
from astToolkit import IfThis as astToolkit_IfThis
|
|
22
|
+
from astToolkit import ast_Identifier, Be, DOT, IfThis as astToolkit_IfThis
|
|
23
23
|
from collections.abc import Callable
|
|
24
|
-
from mapFolding.someAssemblyRequired import ast_Identifier, Be, DOT
|
|
25
24
|
from typing import TypeGuard
|
|
26
25
|
import ast
|
|
27
26
|
|