mapFolding 0.15.4__py3-none-any.whl → 0.16.0__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 +7 -9
- mapFolding/_theSSOT.py +1 -0
- mapFolding/algorithms/daoOfMapFolding.py +1 -2
- mapFolding/algorithms/getBucketsTotal.py +137 -0
- mapFolding/algorithms/matrixMeanders.py +457 -286
- mapFolding/algorithms/oeisIDbyFormula.py +310 -76
- mapFolding/algorithms/zCuzDocStoopidoeisIDbyFormula.py +84 -0
- mapFolding/basecamp.py +99 -14
- mapFolding/dataBaskets.py +74 -0
- mapFolding/oeis.py +3 -2
- mapFolding/reference/A000682facts.py +662 -0
- mapFolding/reference/A005316facts.py +62 -0
- mapFolding/reference/matrixMeandersAnalysis/__init__.py +1 -0
- mapFolding/reference/matrixMeandersAnalysis/evenEven.py +144 -0
- mapFolding/reference/matrixMeandersAnalysis/oddEven.py +54 -0
- mapFolding/someAssemblyRequired/A007822/A007822rawMaterials.py +55 -0
- mapFolding/someAssemblyRequired/A007822/__init__.py +0 -0
- mapFolding/someAssemblyRequired/A007822/makeA007822AsynchronousModules.py +185 -0
- mapFolding/someAssemblyRequired/A007822/makeA007822Modules.py +71 -0
- mapFolding/someAssemblyRequired/RecipeJob.py +2 -2
- mapFolding/someAssemblyRequired/__init__.py +9 -2
- mapFolding/someAssemblyRequired/_toolIfThis.py +4 -3
- mapFolding/someAssemblyRequired/_toolkitContainers.py +8 -8
- mapFolding/someAssemblyRequired/infoBooth.py +27 -30
- mapFolding/someAssemblyRequired/makeJobTheorem2Numba.py +1 -1
- mapFolding/someAssemblyRequired/makeJobTheorem2codon.py +5 -2
- mapFolding/someAssemblyRequired/makingModules_count.py +301 -0
- mapFolding/someAssemblyRequired/makingModules_doTheNeedful.py +120 -0
- mapFolding/someAssemblyRequired/mapFolding/__init__.py +0 -0
- mapFolding/someAssemblyRequired/mapFolding/makeMapFoldingModules.py +220 -0
- mapFolding/someAssemblyRequired/toolkitMakeModules.py +152 -0
- mapFolding/someAssemblyRequired/toolkitNumba.py +1 -1
- mapFolding/someAssemblyRequired/transformationTools.py +1 -0
- mapFolding/syntheticModules/A007822/__init__.py +1 -0
- mapFolding/syntheticModules/{algorithmA007822Numba.py → A007822/algorithmNumba.py} +2 -4
- mapFolding/syntheticModules/A007822/asynchronous.py +148 -0
- mapFolding/syntheticModules/A007822/asynchronousAnnex.py +68 -0
- mapFolding/syntheticModules/A007822/asynchronousTheorem2.py +53 -0
- mapFolding/syntheticModules/A007822/asynchronousTrimmed.py +47 -0
- mapFolding/syntheticModules/dataPackingA007822.py +1 -1
- mapFolding/tests/test_computations.py +2 -2
- mapFolding/trim_memory.py +62 -0
- mapFolding/zCuzDocStoopid/__init__.py +1 -0
- mapFolding/zCuzDocStoopid/makeDocstrings.py +63 -0
- {mapfolding-0.15.4.dist-info → mapfolding-0.16.0.dist-info}/METADATA +9 -2
- mapfolding-0.16.0.dist-info/RECORD +100 -0
- mapFolding/someAssemblyRequired/A007822rawMaterials.py +0 -46
- mapFolding/someAssemblyRequired/makeAllModules.py +0 -764
- mapfolding-0.15.4.dist-info/RECORD +0 -78
- /mapFolding/syntheticModules/{algorithmA007822.py → A007822/algorithm.py} +0 -0
- /mapFolding/syntheticModules/{initializeStateA007822.py → A007822/initializeState.py} +0 -0
- /mapFolding/syntheticModules/{theorem2A007822.py → A007822/theorem2.py} +0 -0
- /mapFolding/syntheticModules/{theorem2A007822Numba.py → A007822/theorem2Numba.py} +0 -0
- /mapFolding/syntheticModules/{theorem2A007822Trimmed.py → A007822/theorem2Trimmed.py} +0 -0
- {mapfolding-0.15.4.dist-info → mapfolding-0.16.0.dist-info}/WHEEL +0 -0
- {mapfolding-0.15.4.dist-info → mapfolding-0.16.0.dist-info}/entry_points.txt +0 -0
- {mapfolding-0.15.4.dist-info → mapfolding-0.16.0.dist-info}/licenses/LICENSE +0 -0
- {mapfolding-0.15.4.dist-info → mapfolding-0.16.0.dist-info}/top_level.txt +0 -0
|
@@ -11,42 +11,39 @@ on empirical measurements and theoretical analysis of map folding algorithms for
|
|
|
11
11
|
specific dimensional configurations.
|
|
12
12
|
"""
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
dataclassInstanceIdentifierDEFAULT: str = 'state'
|
|
18
|
-
"""Default variable name for dataclass instances in generated code."""
|
|
19
|
-
|
|
20
|
-
dataPackingModuleIdentifierDEFAULT: str = 'dataPacking'
|
|
21
|
-
"""Default identifier for modules containing data packing and unpacking functions."""
|
|
22
|
-
|
|
23
|
-
logicalPathInfixDEFAULT: str = 'syntheticModules'
|
|
24
|
-
"""Default path component for organizing synthetic generated modules."""
|
|
25
|
-
|
|
26
|
-
sourceCallableDispatcherDEFAULT: str = 'doTheNeedful'
|
|
27
|
-
"""Default identifier for dispatcher functions that route computational tasks."""
|
|
28
|
-
|
|
29
|
-
sourceCallableIdentifierDEFAULT: str = 'count'
|
|
30
|
-
"""Default identifier for the core counting function in algorithms."""
|
|
14
|
+
from hunterMakesPy import identifierDotAttribute
|
|
15
|
+
from typing import Final
|
|
31
16
|
|
|
32
|
-
|
|
33
|
-
"""Default identifier for the primary counting variable in map folding computations."""
|
|
34
|
-
|
|
35
|
-
dictionaryEstimates: dict[tuple[int, ...], int] = {
|
|
17
|
+
dictionaryEstimatesMapFolding: Final[dict[tuple[int, ...], int]] = {
|
|
36
18
|
(2,2,2,2,2,2,2,2): 798148657152000,
|
|
37
19
|
(2,21): 776374224866624,
|
|
38
20
|
(3,15): 824761667826225,
|
|
39
21
|
(3,3,3,3): 85109616000000000000000000000000,
|
|
40
22
|
(8,8): 791274195985524900,
|
|
41
23
|
}
|
|
42
|
-
"""
|
|
43
|
-
Registry of computational complexity estimates for specific map dimension configurations.
|
|
24
|
+
"""Estimates of multidimensional map folding `foldsTotal`."""
|
|
44
25
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
26
|
+
identifierCallableSourceDEFAULT: Final[str] = 'count'
|
|
27
|
+
"""Default identifier for the core counting function in algorithms."""
|
|
28
|
+
|
|
29
|
+
identifierCallableSourceDispatcherDEFAULT: Final[str] = 'doTheNeedful'
|
|
30
|
+
"""Default identifier for dispatcher functions that route computational tasks."""
|
|
31
|
+
|
|
32
|
+
identifierCountingDEFAULT: Final[str] = 'groupsOfFolds'
|
|
33
|
+
"""Default identifier for the primary counting variable in map folding computations."""
|
|
34
|
+
|
|
35
|
+
identifierDataclassInstanceDEFAULT: Final[str] = 'state'
|
|
36
|
+
"""Default variable name for dataclass instances in generated code."""
|
|
37
|
+
|
|
38
|
+
identifierModuleDataPackingDEFAULT: Final[str] = 'dataPacking'
|
|
39
|
+
"""Default identifier for modules containing data packing and unpacking functions."""
|
|
40
|
+
|
|
41
|
+
identifierModuleSourceAlgorithmDEFAULT: Final[str] = 'daoOfMapFolding'
|
|
42
|
+
"""Default identifier for the algorithm source module containing the base implementation."""
|
|
43
|
+
|
|
44
|
+
logicalPathInfixAlgorithmDEFAULT: Final[identifierDotAttribute] = 'algorithms'
|
|
45
|
+
"""Default logical path component for handmade algorithms."""
|
|
46
|
+
|
|
47
|
+
logicalPathInfixDEFAULT: Final[identifierDotAttribute] = 'syntheticModules'
|
|
48
|
+
"""Default logical path component for organizing synthetic generated modules."""
|
|
48
49
|
|
|
49
|
-
The estimates represent the expected number of computational operations or fold
|
|
50
|
-
configurations for the given map dimensions, helping determine appropriate optimization
|
|
51
|
-
strategies and computational resource allocation.
|
|
52
|
-
"""
|
|
@@ -326,7 +326,7 @@ if __name__ == '__main__':
|
|
|
326
326
|
"""
|
|
327
327
|
|
|
328
328
|
if __name__ == '__main__':
|
|
329
|
-
state = transitionOnGroupsOfFolds(MapFoldingState((
|
|
329
|
+
state = transitionOnGroupsOfFolds(MapFoldingState((1,27)))
|
|
330
330
|
pathModule = PurePosixPath(packageSettings.pathPackage, 'jobs')
|
|
331
331
|
pathFilenameFoldsTotal = PurePosixPath(getPathFilenameFoldsTotal(state.mapShape, pathModule))
|
|
332
332
|
aJob = RecipeJobTheorem2(state, pathModule=pathModule, pathFilenameFoldsTotal=pathFilenameFoldsTotal)
|
|
@@ -100,7 +100,9 @@ def _variableCompatibility(ingredientsFunction: IngredientsFunction, job: Recipe
|
|
|
100
100
|
# `identifier` in Augmented Assignment, or in Assignments and value is Constant.
|
|
101
101
|
NodeChanger(findThis=IfThis.isAnyOf(
|
|
102
102
|
Be.AugAssign.targetIs(IfThis.isNestedNameIdentifier(identifier))
|
|
103
|
-
, IfThis.isAllOf(
|
|
103
|
+
, IfThis.isAllOf(
|
|
104
|
+
Be.Assign.targetsIs(Be.at(0, IfThis.isNestedNameIdentifier(identifier)))
|
|
105
|
+
# IfThis.isAssignAndTargets0Is(IfThis.isNameIdentifier(identifier))
|
|
104
106
|
, Be.Assign.valueIs(Be.Constant))
|
|
105
107
|
)
|
|
106
108
|
, doThat=lambda node, annotation=annotation: Grab.valueAttribute(Then.replaceWith(Make.Call(annotation, listParameters=[node.value])))(node)
|
|
@@ -113,6 +115,7 @@ def _variableCompatibility(ingredientsFunction: IngredientsFunction, job: Recipe
|
|
|
113
115
|
|
|
114
116
|
# `identifier` in Comparison.
|
|
115
117
|
NodeChanger(Be.Compare.leftIs(IfThis.isNestedNameIdentifier(identifier))
|
|
118
|
+
# , doThat=Grab.comparatorsAttribute(Grab.index(0, lambda comparator, annotation=annotation: Then.replaceWith(Make.Call(annotation, listParameters=[comparator]))))
|
|
116
119
|
, doThat=lambda node, annotation=annotation: Grab.comparatorsAttribute(lambda at, annotation=annotation: Then.replaceWith([Make.Call(annotation, listParameters=[node.comparators[0]])])(at[0]))(node)
|
|
117
120
|
).visit(ingredientsFunction.astFunctionDef)
|
|
118
121
|
|
|
@@ -220,6 +223,6 @@ def fromMapShape(mapShape: tuple[DatatypeLeavesTotal, ...]) -> None:
|
|
|
220
223
|
makeJob(aJob)
|
|
221
224
|
|
|
222
225
|
if __name__ == '__main__':
|
|
223
|
-
mapShape = (1,
|
|
226
|
+
mapShape = (1, 3)
|
|
224
227
|
fromMapShape(mapShape)
|
|
225
228
|
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
"""Make the `count` function for an algorithm.
|
|
2
|
+
|
|
3
|
+
These transformation functions will work on at least two different algorithms. If a transformation function only works on a
|
|
4
|
+
specific type of algorithm, it will be in a subdirectory.
|
|
5
|
+
"""
|
|
6
|
+
from astToolkit import (
|
|
7
|
+
astModuleToIngredientsFunction, Be, DOT, Grab, identifierDotAttribute, IngredientsFunction, IngredientsModule,
|
|
8
|
+
LedgerOfImports, Make, NodeChanger, NodeTourist, Then)
|
|
9
|
+
from astToolkit.transformationTools import inlineFunctionDef, removeUnusedParameters, write_astModule
|
|
10
|
+
from hunterMakesPy import raiseIfNone
|
|
11
|
+
from mapFolding import packageSettings
|
|
12
|
+
from mapFolding.someAssemblyRequired import (
|
|
13
|
+
identifierCallableSourceDEFAULT, identifierCountingDEFAULT, IfThis, ShatteredDataclass)
|
|
14
|
+
from mapFolding.someAssemblyRequired.A007822.A007822rawMaterials import astExprCall_filterAsymmetricFoldsLeafBelow
|
|
15
|
+
from mapFolding.someAssemblyRequired.toolkitMakeModules import findDataclass, getPathFilename
|
|
16
|
+
from mapFolding.someAssemblyRequired.toolkitNumba import decorateCallableWithNumba, parametersNumbaLight
|
|
17
|
+
from mapFolding.someAssemblyRequired.transformationTools import (
|
|
18
|
+
removeDataclassFromFunction, shatter_dataclassesDOTdataclass, unpackDataclassCallFunctionRepackDataclass)
|
|
19
|
+
from os import PathLike
|
|
20
|
+
from pathlib import PurePath
|
|
21
|
+
from typing import cast
|
|
22
|
+
import ast
|
|
23
|
+
|
|
24
|
+
def makeDaoOfMapFoldingNumba(astModule: ast.Module, moduleIdentifier: str, callableIdentifier: str | None = None, logicalPathInfix: PathLike[str] | PurePath | str | None = None, sourceCallableDispatcher: str | None = None) -> PurePath:
|
|
25
|
+
"""Generate Numba-optimized sequential implementation of map folding algorithm.
|
|
26
|
+
|
|
27
|
+
(AI generated docstring)
|
|
28
|
+
|
|
29
|
+
Creates a high-performance sequential version of the map folding algorithm by
|
|
30
|
+
decomposing dataclass parameters into individual primitive values, removing
|
|
31
|
+
dataclass dependencies that are incompatible with Numba, applying Numba
|
|
32
|
+
decorators for just-in-time compilation, and optionally including a dispatcher
|
|
33
|
+
function for dataclass integration.
|
|
34
|
+
|
|
35
|
+
The generated module provides significant performance improvements over the
|
|
36
|
+
original dataclass-based implementation while maintaining algorithmic correctness.
|
|
37
|
+
The transformation preserves all computational logic while restructuring data
|
|
38
|
+
access patterns for optimal Numba compilation.
|
|
39
|
+
|
|
40
|
+
Parameters
|
|
41
|
+
----------
|
|
42
|
+
astModule : ast.Module
|
|
43
|
+
Source module containing the base algorithm.
|
|
44
|
+
moduleIdentifier : str
|
|
45
|
+
Name for the generated optimized module.
|
|
46
|
+
callableIdentifier : str | None = None
|
|
47
|
+
Name for the main computational function.
|
|
48
|
+
logicalPathInfix : PathLike[str] | PurePath | str | None = None
|
|
49
|
+
Directory path for organizing the generated module.
|
|
50
|
+
sourceCallableDispatcher : str | None = None
|
|
51
|
+
Optional dispatcher function for dataclass integration.
|
|
52
|
+
|
|
53
|
+
Returns
|
|
54
|
+
-------
|
|
55
|
+
pathFilename : PurePath
|
|
56
|
+
Filesystem path where the optimized module was written.
|
|
57
|
+
|
|
58
|
+
"""
|
|
59
|
+
sourceCallableIdentifier: identifierDotAttribute = identifierCallableSourceDEFAULT
|
|
60
|
+
ingredientsFunction = IngredientsFunction(inlineFunctionDef(sourceCallableIdentifier, astModule), LedgerOfImports(astModule))
|
|
61
|
+
ingredientsFunction.astFunctionDef.name = callableIdentifier or sourceCallableIdentifier
|
|
62
|
+
|
|
63
|
+
shatteredDataclass: ShatteredDataclass = shatter_dataclassesDOTdataclass(*findDataclass(ingredientsFunction))
|
|
64
|
+
|
|
65
|
+
ingredientsFunction.imports.update(shatteredDataclass.imports)
|
|
66
|
+
ingredientsFunction: IngredientsFunction = removeDataclassFromFunction(ingredientsFunction, shatteredDataclass)
|
|
67
|
+
ingredientsFunction = removeUnusedParameters(ingredientsFunction)
|
|
68
|
+
ingredientsFunction = decorateCallableWithNumba(ingredientsFunction, parametersNumbaLight)
|
|
69
|
+
|
|
70
|
+
ingredientsModule = IngredientsModule(ingredientsFunction)
|
|
71
|
+
|
|
72
|
+
if sourceCallableDispatcher is not None:
|
|
73
|
+
|
|
74
|
+
ingredientsFunctionDispatcher: IngredientsFunction = astModuleToIngredientsFunction(astModule, sourceCallableDispatcher)
|
|
75
|
+
ingredientsFunctionDispatcher.imports.update(shatteredDataclass.imports)
|
|
76
|
+
targetCallableIdentifier = ingredientsFunction.astFunctionDef.name
|
|
77
|
+
ingredientsFunctionDispatcher = unpackDataclassCallFunctionRepackDataclass(ingredientsFunctionDispatcher, targetCallableIdentifier, shatteredDataclass)
|
|
78
|
+
astTuple: ast.Tuple = cast('ast.Tuple', raiseIfNone(NodeTourist(Be.Return.valueIs(Be.Tuple)
|
|
79
|
+
, doThat=Then.extractIt(DOT.value)).captureLastMatch(ingredientsFunction.astFunctionDef)))
|
|
80
|
+
astTuple.ctx = Make.Store()
|
|
81
|
+
|
|
82
|
+
changeAssignCallToTarget = NodeChanger(
|
|
83
|
+
findThis = Be.Assign.valueIs(IfThis.isCallIdentifier(targetCallableIdentifier))
|
|
84
|
+
, doThat = Then.replaceWith(Make.Assign([astTuple], value=Make.Call(Make.Name(targetCallableIdentifier), astTuple.elts))))
|
|
85
|
+
changeAssignCallToTarget.visit(ingredientsFunctionDispatcher.astFunctionDef)
|
|
86
|
+
|
|
87
|
+
ingredientsModule.appendIngredientsFunction(ingredientsFunctionDispatcher)
|
|
88
|
+
|
|
89
|
+
ingredientsModule.removeImportFromModule('numpy')
|
|
90
|
+
|
|
91
|
+
pathFilename: PurePath = getPathFilename(packageSettings.pathPackage, logicalPathInfix, moduleIdentifier)
|
|
92
|
+
|
|
93
|
+
write_astModule(ingredientsModule, pathFilename, packageSettings.identifierPackage)
|
|
94
|
+
|
|
95
|
+
return pathFilename
|
|
96
|
+
|
|
97
|
+
def makeTheorem2(astModule: ast.Module, moduleIdentifier: str, callableIdentifier: str | None = None, logicalPathInfix: PathLike[str] | PurePath | str | None = None, sourceCallableDispatcher: str | None = None) -> PurePath:
|
|
98
|
+
"""Generate module by applying optimization predicted by Theorem 2.
|
|
99
|
+
|
|
100
|
+
Parameters
|
|
101
|
+
----------
|
|
102
|
+
astModule : ast.Module
|
|
103
|
+
Source module containing the base algorithm.
|
|
104
|
+
moduleIdentifier : str
|
|
105
|
+
Name for the generated theorem-optimized module.
|
|
106
|
+
callableIdentifier : str | None = None
|
|
107
|
+
Name for the optimized computational function.
|
|
108
|
+
logicalPathInfix : PathLike[str] | PurePath | str | None = None
|
|
109
|
+
Directory path for organizing the generated module.
|
|
110
|
+
sourceCallableDispatcher : str | None = None
|
|
111
|
+
Currently not implemented for this transformation.
|
|
112
|
+
|
|
113
|
+
Returns
|
|
114
|
+
-------
|
|
115
|
+
pathFilename : PurePath
|
|
116
|
+
Filesystem path where the theorem-optimized module was written.
|
|
117
|
+
|
|
118
|
+
Raises
|
|
119
|
+
------
|
|
120
|
+
NotImplementedError
|
|
121
|
+
If `sourceCallableDispatcher` is provided.
|
|
122
|
+
|
|
123
|
+
"""
|
|
124
|
+
sourceCallableIdentifier = identifierCallableSourceDEFAULT
|
|
125
|
+
ingredientsFunction = IngredientsFunction(inlineFunctionDef(sourceCallableIdentifier, astModule), LedgerOfImports(astModule))
|
|
126
|
+
ingredientsFunction.astFunctionDef.name = callableIdentifier or sourceCallableIdentifier
|
|
127
|
+
|
|
128
|
+
dataclassInstanceIdentifier: identifierDotAttribute = raiseIfNone(NodeTourist(Be.arg, Then.extractIt(DOT.arg)).captureLastMatch(ingredientsFunction.astFunctionDef))
|
|
129
|
+
|
|
130
|
+
theCountingIdentifier: identifierDotAttribute = identifierCountingDEFAULT
|
|
131
|
+
doubleTheCount: ast.AugAssign = Make.AugAssign(Make.Attribute(Make.Name(dataclassInstanceIdentifier), theCountingIdentifier), Make.Mult(), Make.Constant(2))
|
|
132
|
+
|
|
133
|
+
NodeChanger(
|
|
134
|
+
findThis = IfThis.isAllOf(
|
|
135
|
+
IfThis.isWhileAttributeNamespaceIdentifierGreaterThan0(dataclassInstanceIdentifier, 'leaf1ndex')
|
|
136
|
+
, Be.While.orelseIs(lambda ImaList: ImaList))
|
|
137
|
+
, doThat = Grab.orelseAttribute(Grab.index(0, Then.insertThisBelow([doubleTheCount])))
|
|
138
|
+
).visit(ingredientsFunction.astFunctionDef)
|
|
139
|
+
|
|
140
|
+
NodeChanger(
|
|
141
|
+
findThis = IfThis.isAllOf(
|
|
142
|
+
IfThis.isWhileAttributeNamespaceIdentifierGreaterThan0(dataclassInstanceIdentifier, 'leaf1ndex')
|
|
143
|
+
, Be.While.orelseIs(lambda ImaList: not ImaList))
|
|
144
|
+
, doThat = Grab.orelseAttribute(Then.replaceWith([doubleTheCount]))
|
|
145
|
+
).visit(ingredientsFunction.astFunctionDef)
|
|
146
|
+
|
|
147
|
+
NodeChanger(
|
|
148
|
+
findThis = IfThis.isWhileAttributeNamespaceIdentifierGreaterThan0(dataclassInstanceIdentifier, 'leaf1ndex')
|
|
149
|
+
, doThat = Grab.testAttribute(Grab.comparatorsAttribute(Then.replaceWith([Make.Constant(4)])))
|
|
150
|
+
).visit(ingredientsFunction.astFunctionDef)
|
|
151
|
+
|
|
152
|
+
insertLeaf = NodeTourist(
|
|
153
|
+
findThis = IfThis.isIfAttributeNamespaceIdentifierGreaterThan0(dataclassInstanceIdentifier, 'leaf1ndex')
|
|
154
|
+
, doThat = Then.extractIt(DOT.body)
|
|
155
|
+
).captureLastMatch(ingredientsFunction.astFunctionDef)
|
|
156
|
+
NodeChanger(
|
|
157
|
+
findThis = IfThis.isIfAttributeNamespaceIdentifierGreaterThan0(dataclassInstanceIdentifier, 'leaf1ndex')
|
|
158
|
+
, doThat = Then.replaceWith(insertLeaf)
|
|
159
|
+
).visit(ingredientsFunction.astFunctionDef)
|
|
160
|
+
|
|
161
|
+
NodeChanger(
|
|
162
|
+
findThis = IfThis.isAttributeNamespaceIdentifierGreaterThan0(dataclassInstanceIdentifier, 'leaf1ndex')
|
|
163
|
+
, doThat = Then.removeIt
|
|
164
|
+
).visit(ingredientsFunction.astFunctionDef)
|
|
165
|
+
|
|
166
|
+
NodeChanger(
|
|
167
|
+
findThis = IfThis.isAttributeNamespaceIdentifierLessThanOrEqual0(dataclassInstanceIdentifier, 'leaf1ndex')
|
|
168
|
+
, doThat = Then.removeIt
|
|
169
|
+
).visit(ingredientsFunction.astFunctionDef)
|
|
170
|
+
|
|
171
|
+
ingredientsModule = IngredientsModule(ingredientsFunction)
|
|
172
|
+
|
|
173
|
+
if sourceCallableDispatcher is not None:
|
|
174
|
+
message = 'sourceCallableDispatcher is not implemented yet'
|
|
175
|
+
raise NotImplementedError(message)
|
|
176
|
+
|
|
177
|
+
pathFilename: PurePath = getPathFilename(packageSettings.pathPackage, logicalPathInfix, moduleIdentifier)
|
|
178
|
+
|
|
179
|
+
write_astModule(ingredientsModule, pathFilename, packageSettings.identifierPackage)
|
|
180
|
+
|
|
181
|
+
return pathFilename
|
|
182
|
+
|
|
183
|
+
def numbaOnTheorem2(astModule: ast.Module, moduleIdentifier: str, callableIdentifier: str | None = None, logicalPathInfix: PathLike[str] | PurePath | str | None = None, sourceCallableDispatcher: str | None = None) -> PurePath:
|
|
184
|
+
"""Generate Numba-accelerated Theorem 2 implementation with dataclass decomposition.
|
|
185
|
+
|
|
186
|
+
(AI generated docstring)
|
|
187
|
+
|
|
188
|
+
Creates a highly optimized version of the Theorem 2 algorithm by combining the
|
|
189
|
+
mathematical optimizations of Theorem 2 with Numba just-in-time compilation.
|
|
190
|
+
The transformation includes dataclass decomposition to convert structured
|
|
191
|
+
parameters into primitives, removal of Python object dependencies incompatible
|
|
192
|
+
with Numba, application of Numba decorators for maximum performance, and type
|
|
193
|
+
annotation optimization for efficient compilation.
|
|
194
|
+
|
|
195
|
+
This represents the highest level of optimization available for Theorem 2
|
|
196
|
+
implementations, providing both mathematical efficiency through theorem
|
|
197
|
+
application and computational efficiency through Numba acceleration.
|
|
198
|
+
The result is suitable for production use in high-performance computing
|
|
199
|
+
environments where maximum speed is required.
|
|
200
|
+
|
|
201
|
+
Parameters
|
|
202
|
+
----------
|
|
203
|
+
astModule : ast.Module
|
|
204
|
+
Source module containing the Theorem 2 implementation.
|
|
205
|
+
moduleIdentifier : str
|
|
206
|
+
Name for the generated Numba-accelerated module.
|
|
207
|
+
callableIdentifier : str | None = None
|
|
208
|
+
Name for the accelerated computational function.
|
|
209
|
+
logicalPathInfix : PathLike[str] | PurePath | str | None = None
|
|
210
|
+
Directory path for organizing the generated module.
|
|
211
|
+
sourceCallableDispatcher : str | None = None
|
|
212
|
+
Optional dispatcher function identifier (unused).
|
|
213
|
+
|
|
214
|
+
Returns
|
|
215
|
+
-------
|
|
216
|
+
pathFilename : PurePath
|
|
217
|
+
Filesystem path where the accelerated module was written.
|
|
218
|
+
|
|
219
|
+
"""
|
|
220
|
+
sourceCallableIdentifier = identifierCallableSourceDEFAULT
|
|
221
|
+
if callableIdentifier is None:
|
|
222
|
+
callableIdentifier = sourceCallableIdentifier
|
|
223
|
+
ingredientsFunction = IngredientsFunction(inlineFunctionDef(sourceCallableIdentifier, astModule), LedgerOfImports(astModule))
|
|
224
|
+
ingredientsFunction.astFunctionDef.name = callableIdentifier
|
|
225
|
+
|
|
226
|
+
shatteredDataclass: ShatteredDataclass = shatter_dataclassesDOTdataclass(*findDataclass(ingredientsFunction))
|
|
227
|
+
|
|
228
|
+
ingredientsFunction.imports.update(shatteredDataclass.imports)
|
|
229
|
+
ingredientsFunction: IngredientsFunction = removeDataclassFromFunction(ingredientsFunction, shatteredDataclass)
|
|
230
|
+
|
|
231
|
+
if sourceCallableDispatcher is not None:
|
|
232
|
+
NodeChanger(
|
|
233
|
+
findThis=IfThis.isCallIdentifier(sourceCallableDispatcher)
|
|
234
|
+
, doThat=Then.replaceWith(astExprCall_filterAsymmetricFoldsLeafBelow)
|
|
235
|
+
).visit(ingredientsFunction.astFunctionDef)
|
|
236
|
+
|
|
237
|
+
ingredientsFunction = removeUnusedParameters(ingredientsFunction)
|
|
238
|
+
ingredientsFunction = decorateCallableWithNumba(ingredientsFunction, parametersNumbaLight)
|
|
239
|
+
|
|
240
|
+
ingredientsModule = IngredientsModule(ingredientsFunction)
|
|
241
|
+
ingredientsModule.removeImportFromModule('numpy')
|
|
242
|
+
|
|
243
|
+
pathFilename: PurePath = getPathFilename(packageSettings.pathPackage, logicalPathInfix, moduleIdentifier)
|
|
244
|
+
|
|
245
|
+
write_astModule(ingredientsModule, pathFilename, packageSettings.identifierPackage)
|
|
246
|
+
|
|
247
|
+
return pathFilename
|
|
248
|
+
|
|
249
|
+
def trimTheorem2(astModule: ast.Module, moduleIdentifier: str, callableIdentifier: str | None = None, logicalPathInfix: PathLike[str] | PurePath | str | None = None, sourceCallableDispatcher: str | None = None) -> PurePath: # noqa: ARG001
|
|
250
|
+
"""Generate constrained Theorem 2 implementation by removing unnecessary logic.
|
|
251
|
+
|
|
252
|
+
(AI generated docstring)
|
|
253
|
+
|
|
254
|
+
Creates a trimmed version of the Theorem 2 implementation by eliminating conditional logic that is not needed under specific
|
|
255
|
+
constraint assumptions. This transformation removes checks for unconstrained dimensions, simplifying the algorithm for cases
|
|
256
|
+
where dimensional constraints are guaranteed to be satisfied by external conditions.
|
|
257
|
+
|
|
258
|
+
The trimming operation is particularly valuable for generating lean implementations where the calling context ensures that
|
|
259
|
+
certain conditions will always be met, allowing the removal of defensive programming constructs that add computational
|
|
260
|
+
overhead without providing benefits in the constrained environment.
|
|
261
|
+
|
|
262
|
+
Parameters
|
|
263
|
+
----------
|
|
264
|
+
astModule : ast.Module
|
|
265
|
+
Source module containing the Theorem 2 implementation.
|
|
266
|
+
moduleIdentifier : str
|
|
267
|
+
Name for the generated trimmed module.
|
|
268
|
+
callableIdentifier : str | None = None
|
|
269
|
+
Name for the trimmed computational function.
|
|
270
|
+
logicalPathInfix : PathLike[str] | PurePath | str | None = None
|
|
271
|
+
Directory path for organizing the generated module.
|
|
272
|
+
sourceCallableDispatcher : str | None = None
|
|
273
|
+
Optional dispatcher function identifier (unused).
|
|
274
|
+
|
|
275
|
+
Returns
|
|
276
|
+
-------
|
|
277
|
+
pathFilename : PurePath
|
|
278
|
+
Filesystem path where the trimmed module was written.
|
|
279
|
+
|
|
280
|
+
"""
|
|
281
|
+
sourceCallableIdentifier = identifierCallableSourceDEFAULT
|
|
282
|
+
ingredientsFunction = IngredientsFunction(inlineFunctionDef(sourceCallableIdentifier, astModule), LedgerOfImports(astModule))
|
|
283
|
+
ingredientsFunction.astFunctionDef.name = callableIdentifier or sourceCallableIdentifier
|
|
284
|
+
|
|
285
|
+
dataclassInstanceIdentifier: identifierDotAttribute = raiseIfNone(NodeTourist(Be.arg, Then.extractIt(DOT.arg)).captureLastMatch(ingredientsFunction.astFunctionDef))
|
|
286
|
+
|
|
287
|
+
findThis = IfThis.isIfUnaryNotAttributeNamespaceIdentifier(dataclassInstanceIdentifier, 'dimensionsUnconstrained')
|
|
288
|
+
doThat = Then.removeIt
|
|
289
|
+
NodeChanger(findThis, doThat).visit(ingredientsFunction.astFunctionDef)
|
|
290
|
+
|
|
291
|
+
ingredientsModule = IngredientsModule(ingredientsFunction)
|
|
292
|
+
ingredientsModule.removeImportFromModule('numpy')
|
|
293
|
+
|
|
294
|
+
pathFilename: PurePath = getPathFilename(packageSettings.pathPackage, logicalPathInfix, moduleIdentifier)
|
|
295
|
+
|
|
296
|
+
write_astModule(ingredientsModule, pathFilename, packageSettings.identifierPackage)
|
|
297
|
+
|
|
298
|
+
return pathFilename
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"""Make functions that are complementary to the `count` function and are often called by `doTheNeedful`."""
|
|
2
|
+
from astToolkit import (
|
|
3
|
+
astModuleToIngredientsFunction, Be, DOT, extractFunctionDef, Grab, identifierDotAttribute, IngredientsFunction,
|
|
4
|
+
IngredientsModule, LedgerOfImports, Make, NodeChanger, NodeTourist, parseLogicalPath2astModule, Then)
|
|
5
|
+
from astToolkit.transformationTools import inlineFunctionDef, write_astModule
|
|
6
|
+
from hunterMakesPy import raiseIfNone
|
|
7
|
+
from mapFolding import packageSettings
|
|
8
|
+
from mapFolding.someAssemblyRequired import (
|
|
9
|
+
identifierCallableSourceDEFAULT, identifierCallableSourceDispatcherDEFAULT, identifierCountingDEFAULT,
|
|
10
|
+
identifierModuleDataPackingDEFAULT, identifierModuleSourceAlgorithmDEFAULT, IfThis, logicalPathInfixAlgorithmDEFAULT,
|
|
11
|
+
logicalPathInfixDEFAULT, ShatteredDataclass)
|
|
12
|
+
from mapFolding.someAssemblyRequired.toolkitMakeModules import findDataclass, getPathFilename
|
|
13
|
+
from mapFolding.someAssemblyRequired.transformationTools import (
|
|
14
|
+
shatter_dataclassesDOTdataclass, unpackDataclassCallFunctionRepackDataclass)
|
|
15
|
+
from os import PathLike
|
|
16
|
+
from pathlib import PurePath
|
|
17
|
+
from typing import cast
|
|
18
|
+
import ast
|
|
19
|
+
|
|
20
|
+
def makeInitializeState(astModule: ast.Module, moduleIdentifier: str, callableIdentifier: str | None = None, logicalPathInfix: PathLike[str] | PurePath | str | None = None, sourceCallableDispatcher: str | None = None) -> PurePath: # noqa: ARG001
|
|
21
|
+
"""Generate initialization module for counting variable setup.
|
|
22
|
+
|
|
23
|
+
(AI generated docstring)
|
|
24
|
+
|
|
25
|
+
Creates a specialized module containing initialization logic for the counting variables
|
|
26
|
+
used in map folding computations. The generated function transforms the original
|
|
27
|
+
algorithm's loop conditions to use equality comparisons instead of greater-than
|
|
28
|
+
comparisons, optimizing the initialization phase.
|
|
29
|
+
|
|
30
|
+
This transformation is particularly important for ensuring that counting variables
|
|
31
|
+
are properly initialized before the main computational loops begin executing.
|
|
32
|
+
|
|
33
|
+
Parameters
|
|
34
|
+
----------
|
|
35
|
+
astModule : ast.Module
|
|
36
|
+
Source module containing the base algorithm.
|
|
37
|
+
moduleIdentifier : str
|
|
38
|
+
Name for the generated initialization module.
|
|
39
|
+
callableIdentifier : str | None = None
|
|
40
|
+
Name for the initialization function.
|
|
41
|
+
logicalPathInfix : PathLike[str] | PurePath | str | None = None
|
|
42
|
+
Directory path for organizing the generated module.
|
|
43
|
+
sourceCallableDispatcher : str | None = None
|
|
44
|
+
Optional dispatcher function identifier.
|
|
45
|
+
|
|
46
|
+
Returns
|
|
47
|
+
-------
|
|
48
|
+
pathFilename : PurePath
|
|
49
|
+
Filesystem path where the initialization module was written.
|
|
50
|
+
|
|
51
|
+
"""
|
|
52
|
+
sourceCallableIdentifier: identifierDotAttribute = identifierCallableSourceDEFAULT
|
|
53
|
+
ingredientsFunction = IngredientsFunction(inlineFunctionDef(sourceCallableIdentifier, astModule), LedgerOfImports(astModule))
|
|
54
|
+
ingredientsFunction.astFunctionDef.name = callableIdentifier or sourceCallableIdentifier
|
|
55
|
+
|
|
56
|
+
dataclassInstanceIdentifier: identifierDotAttribute = raiseIfNone(NodeTourist(Be.arg, Then.extractIt(DOT.arg)).captureLastMatch(ingredientsFunction.astFunctionDef))
|
|
57
|
+
theCountingIdentifier: identifierDotAttribute = identifierCountingDEFAULT
|
|
58
|
+
|
|
59
|
+
findThis = IfThis.isWhileAttributeNamespaceIdentifierGreaterThan0(dataclassInstanceIdentifier, 'leaf1ndex')
|
|
60
|
+
doThat = Grab.testAttribute(Grab.andDoAllOf([Grab.opsAttribute(Then.replaceWith([ast.Eq()])), Grab.leftAttribute(Grab.attrAttribute(Then.replaceWith(theCountingIdentifier)))]))
|
|
61
|
+
NodeChanger(findThis, doThat).visit(ingredientsFunction.astFunctionDef.body[0])
|
|
62
|
+
|
|
63
|
+
pathFilename: PurePath = getPathFilename(packageSettings.pathPackage, logicalPathInfix, moduleIdentifier)
|
|
64
|
+
write_astModule(IngredientsModule(ingredientsFunction), pathFilename, packageSettings.identifierPackage)
|
|
65
|
+
|
|
66
|
+
return pathFilename
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def makeUnRePackDataclass(astImportFrom: ast.ImportFrom, moduleIdentifier: str = identifierModuleDataPackingDEFAULT) -> None:
|
|
70
|
+
"""Generate interface module for dataclass unpacking and repacking operations.
|
|
71
|
+
|
|
72
|
+
Parameters
|
|
73
|
+
----------
|
|
74
|
+
astImportFrom : ast.ImportFrom
|
|
75
|
+
Import statement specifying the target optimized function to call.
|
|
76
|
+
|
|
77
|
+
Returns
|
|
78
|
+
-------
|
|
79
|
+
None
|
|
80
|
+
The generated module is written directly to the filesystem.
|
|
81
|
+
|
|
82
|
+
"""
|
|
83
|
+
callableIdentifierHARDCODED: str = 'sequential'
|
|
84
|
+
|
|
85
|
+
algorithmSourceModule: identifierDotAttribute = identifierModuleSourceAlgorithmDEFAULT
|
|
86
|
+
callableIdentifier: identifierDotAttribute = callableIdentifierHARDCODED
|
|
87
|
+
logicalPathInfix: identifierDotAttribute = logicalPathInfixDEFAULT
|
|
88
|
+
logicalPathInfixAlgorithm: identifierDotAttribute = logicalPathInfixAlgorithmDEFAULT
|
|
89
|
+
sourceCallableIdentifier: identifierDotAttribute = identifierCallableSourceDispatcherDEFAULT
|
|
90
|
+
|
|
91
|
+
logicalPathSourceModule: identifierDotAttribute = '.'.join([packageSettings.identifierPackage, logicalPathInfixAlgorithm, algorithmSourceModule]) # noqa: FLY002
|
|
92
|
+
|
|
93
|
+
ingredientsFunction: IngredientsFunction = astModuleToIngredientsFunction(parseLogicalPath2astModule(logicalPathSourceModule), sourceCallableIdentifier)
|
|
94
|
+
ingredientsFunction.astFunctionDef.name = callableIdentifier
|
|
95
|
+
|
|
96
|
+
shatteredDataclass: ShatteredDataclass = shatter_dataclassesDOTdataclass(*findDataclass(ingredientsFunction))
|
|
97
|
+
|
|
98
|
+
ingredientsFunction.imports.update(shatteredDataclass.imports)
|
|
99
|
+
ingredientsFunction.imports.addAst(astImportFrom)
|
|
100
|
+
targetCallableIdentifier: str = astImportFrom.names[0].name
|
|
101
|
+
ingredientsFunction = raiseIfNone(unpackDataclassCallFunctionRepackDataclass(ingredientsFunction, targetCallableIdentifier, shatteredDataclass))
|
|
102
|
+
targetFunctionDef: ast.FunctionDef = raiseIfNone(extractFunctionDef(parseLogicalPath2astModule(raiseIfNone(astImportFrom.module)), targetCallableIdentifier))
|
|
103
|
+
astTuple: ast.Tuple = cast('ast.Tuple', raiseIfNone(NodeTourist(Be.Return.valueIs(Be.Tuple)
|
|
104
|
+
, doThat=Then.extractIt(DOT.value)).captureLastMatch(targetFunctionDef)))
|
|
105
|
+
astTuple.ctx = Make.Store()
|
|
106
|
+
|
|
107
|
+
changeAssignCallToTarget = NodeChanger(
|
|
108
|
+
findThis = Be.Assign.valueIs(IfThis.isCallIdentifier(targetCallableIdentifier))
|
|
109
|
+
, doThat = Then.replaceWith(Make.Assign([astTuple], value=Make.Call(Make.Name(targetCallableIdentifier), astTuple.elts))))
|
|
110
|
+
changeAssignCallToTarget.visit(ingredientsFunction.astFunctionDef)
|
|
111
|
+
|
|
112
|
+
ingredientsModule = IngredientsModule(ingredientsFunction)
|
|
113
|
+
ingredientsModule.removeImportFromModule('numpy')
|
|
114
|
+
|
|
115
|
+
pathFilename: PurePath = getPathFilename(packageSettings.pathPackage, logicalPathInfix, moduleIdentifier)
|
|
116
|
+
|
|
117
|
+
write_astModule(ingredientsModule, pathFilename, packageSettings.identifierPackage)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
|
|
File without changes
|