mapFolding 0.15.4__py3-none-any.whl → 0.16.1__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.
- easyRun/A000682.py +25 -0
- easyRun/A005316.py +21 -0
- easyRun/NOTcountingFolds.py +36 -0
- easyRun/__init__.py +0 -0
- easyRun/countFolds.py +41 -0
- easyRun/meanders.py +71 -0
- mapFolding/__init__.py +10 -55
- mapFolding/_dataPacking.py +68 -0
- mapFolding/_theSSOT.py +33 -36
- mapFolding/_theTypes.py +21 -4
- mapFolding/algorithms/daoOfMapFolding.py +1 -2
- mapFolding/algorithms/matrixMeanders.py +101 -348
- mapFolding/algorithms/matrixMeandersBeDry.py +264 -0
- mapFolding/algorithms/matrixMeandersNumPy.py +286 -0
- mapFolding/algorithms/matrixMeandersPandas.py +351 -0
- mapFolding/algorithms/oeisIDbyFormula.py +320 -76
- mapFolding/algorithms/zCuzDocStoopidoeisIDbyFormula.py +92 -0
- mapFolding/basecamp.py +261 -113
- mapFolding/beDRY.py +2 -30
- mapFolding/dataBaskets.py +120 -4
- mapFolding/oeis.py +13 -33
- mapFolding/reference/A000682facts.py +1276 -0
- mapFolding/reference/A005316facts.py +985 -0
- mapFolding/reference/matrixMeandersAnalysis/__init__.py +1 -0
- mapFolding/reference/matrixMeandersAnalysis/prefixNotationNotes.py +15 -0
- mapFolding/reference/meandersDumpingGround/A005316JavaPort.py +1 -1
- mapFolding/reference/meandersDumpingGround/A005316imperative.py +1 -1
- mapFolding/reference/meandersDumpingGround/matrixMeandersNumPyV1finalForm.py +424 -0
- mapFolding/someAssemblyRequired/A007822/A007822rawMaterials.py +54 -0
- mapFolding/someAssemblyRequired/A007822/__init__.py +0 -0
- mapFolding/someAssemblyRequired/A007822/makeA007822AsynchronousModules.py +197 -0
- mapFolding/someAssemblyRequired/A007822/makeA007822Modules.py +74 -0
- mapFolding/someAssemblyRequired/RecipeJob.py +4 -4
- 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 +6 -5
- mapFolding/someAssemblyRequired/makeJobTheorem2codon.py +6 -4
- mapFolding/someAssemblyRequired/makingModules_count.py +294 -0
- mapFolding/someAssemblyRequired/makingModules_doTheNeedful.py +117 -0
- mapFolding/someAssemblyRequired/mapFolding/__init__.py +0 -0
- mapFolding/someAssemblyRequired/mapFolding/makeMapFoldingModules.py +220 -0
- mapFolding/someAssemblyRequired/meanders/__init__.py +0 -0
- mapFolding/someAssemblyRequired/meanders/makeMeandersModules.py +64 -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/{algorithmA007822.py → A007822/algorithm.py} +2 -3
- mapFolding/syntheticModules/{algorithmA007822Numba.py → A007822/algorithmNumba.py} +3 -6
- mapFolding/syntheticModules/A007822/asynchronous.py +148 -0
- mapFolding/syntheticModules/A007822/asynchronousAnnex.py +66 -0
- mapFolding/syntheticModules/A007822/asynchronousAnnexNumba.py +85 -0
- mapFolding/syntheticModules/A007822/asynchronousNumba.py +52 -0
- mapFolding/syntheticModules/A007822/asynchronousTheorem2.py +53 -0
- mapFolding/syntheticModules/A007822/asynchronousTrimmed.py +47 -0
- mapFolding/syntheticModules/{initializeStateA007822.py → A007822/initializeState.py} +1 -2
- mapFolding/syntheticModules/{theorem2A007822.py → A007822/theorem2.py} +1 -2
- mapFolding/syntheticModules/{theorem2A007822Numba.py → A007822/theorem2Numba.py} +6 -4
- mapFolding/syntheticModules/{theorem2A007822Trimmed.py → A007822/theorem2Trimmed.py} +1 -2
- mapFolding/syntheticModules/countParallelNumba.py +5 -2
- mapFolding/syntheticModules/daoOfMapFoldingNumba.py +4 -2
- mapFolding/syntheticModules/dataPacking.py +4 -2
- mapFolding/syntheticModules/dataPackingA007822.py +92 -26
- mapFolding/syntheticModules/meanders/__init__.py +1 -0
- mapFolding/syntheticModules/meanders/bigInt.py +62 -0
- mapFolding/syntheticModules/theorem2Numba.py +3 -2
- mapFolding/tests/conftest.py +28 -13
- mapFolding/tests/test_computations.py +69 -62
- mapFolding/tests/test_oeis.py +6 -6
- mapFolding/zCuzDocStoopid/__init__.py +4 -0
- mapFolding/zCuzDocStoopid/makeDocstrings.py +68 -0
- mapfolding-0.16.1.dist-info/METADATA +99 -0
- mapfolding-0.16.1.dist-info/RECORD +114 -0
- {mapfolding-0.15.4.dist-info → mapfolding-0.16.1.dist-info}/top_level.txt +1 -0
- mapFolding/someAssemblyRequired/A007822rawMaterials.py +0 -46
- mapFolding/someAssemblyRequired/makeAllModules.py +0 -764
- mapfolding-0.15.4.dist-info/METADATA +0 -78
- mapfolding-0.15.4.dist-info/RECORD +0 -78
- {mapfolding-0.15.4.dist-info → mapfolding-0.16.1.dist-info}/WHEEL +0 -0
- {mapfolding-0.15.4.dist-info → mapfolding-0.16.1.dist-info}/entry_points.txt +0 -0
- {mapfolding-0.15.4.dist-info → mapfolding-0.16.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,294 @@
|
|
|
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 | identifierDotAttribute | 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 | identifierDotAttribute | 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 | identifierDotAttribute | None = None, sourceCallableDispatcher: str | None = None) -> PurePath: # noqa: ARG001
|
|
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
|
+
ingredientsFunction = removeUnusedParameters(ingredientsFunction)
|
|
231
|
+
ingredientsFunction = decorateCallableWithNumba(ingredientsFunction, parametersNumbaLight)
|
|
232
|
+
|
|
233
|
+
ingredientsModule = IngredientsModule(ingredientsFunction)
|
|
234
|
+
ingredientsModule.removeImportFromModule('numpy')
|
|
235
|
+
|
|
236
|
+
pathFilename: PurePath = getPathFilename(packageSettings.pathPackage, logicalPathInfix, moduleIdentifier)
|
|
237
|
+
|
|
238
|
+
write_astModule(ingredientsModule, pathFilename, packageSettings.identifierPackage)
|
|
239
|
+
|
|
240
|
+
return pathFilename
|
|
241
|
+
|
|
242
|
+
def trimTheorem2(astModule: ast.Module, moduleIdentifier: str, callableIdentifier: str | None = None, logicalPathInfix: PathLike[str] | PurePath | identifierDotAttribute | None = None, sourceCallableDispatcher: str | None = None) -> PurePath: # noqa: ARG001
|
|
243
|
+
"""Generate constrained Theorem 2 implementation by removing unnecessary logic.
|
|
244
|
+
|
|
245
|
+
(AI generated docstring)
|
|
246
|
+
|
|
247
|
+
Creates a trimmed version of the Theorem 2 implementation by eliminating conditional logic that is not needed under specific
|
|
248
|
+
constraint assumptions. This transformation removes checks for unconstrained dimensions, simplifying the algorithm for cases
|
|
249
|
+
where dimensional constraints are guaranteed to be satisfied by external conditions.
|
|
250
|
+
|
|
251
|
+
The trimming operation is particularly valuable for generating lean implementations where the calling context ensures that
|
|
252
|
+
certain conditions will always be met, allowing the removal of defensive programming constructs that add computational
|
|
253
|
+
overhead without providing benefits in the constrained environment.
|
|
254
|
+
|
|
255
|
+
Parameters
|
|
256
|
+
----------
|
|
257
|
+
astModule : ast.Module
|
|
258
|
+
Source module containing the Theorem 2 implementation.
|
|
259
|
+
moduleIdentifier : str
|
|
260
|
+
Name for the generated trimmed module.
|
|
261
|
+
callableIdentifier : str | None = None
|
|
262
|
+
Name for the trimmed computational function.
|
|
263
|
+
logicalPathInfix : PathLike[str] | PurePath | str | None = None
|
|
264
|
+
Directory path for organizing the generated module.
|
|
265
|
+
sourceCallableDispatcher : str | None = None
|
|
266
|
+
Optional dispatcher function identifier (unused).
|
|
267
|
+
|
|
268
|
+
Returns
|
|
269
|
+
-------
|
|
270
|
+
pathFilename : PurePath
|
|
271
|
+
Filesystem path where the trimmed module was written.
|
|
272
|
+
|
|
273
|
+
"""
|
|
274
|
+
sourceCallableIdentifier = identifierCallableSourceDEFAULT
|
|
275
|
+
ingredientsFunction = IngredientsFunction(inlineFunctionDef(sourceCallableIdentifier, astModule), LedgerOfImports(astModule))
|
|
276
|
+
ingredientsFunction.astFunctionDef.name = callableIdentifier or sourceCallableIdentifier
|
|
277
|
+
|
|
278
|
+
dataclassInstanceIdentifier: identifierDotAttribute = raiseIfNone(NodeTourist(Be.arg, Then.extractIt(DOT.arg)).captureLastMatch(ingredientsFunction.astFunctionDef))
|
|
279
|
+
|
|
280
|
+
findThis = IfThis.isIfUnaryNotAttributeNamespaceIdentifier(dataclassInstanceIdentifier, 'dimensionsUnconstrained')
|
|
281
|
+
doThat = Then.removeIt
|
|
282
|
+
NodeChanger(findThis, doThat).visit(ingredientsFunction.astFunctionDef)
|
|
283
|
+
|
|
284
|
+
ingredientsModule = IngredientsModule(ingredientsFunction)
|
|
285
|
+
ingredientsModule.removeImportFromModule('numpy')
|
|
286
|
+
|
|
287
|
+
pathFilename: PurePath = getPathFilename(packageSettings.pathPackage, logicalPathInfix, moduleIdentifier)
|
|
288
|
+
|
|
289
|
+
write_astModule(ingredientsModule, pathFilename, packageSettings.identifierPackage)
|
|
290
|
+
|
|
291
|
+
return pathFilename
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
|
|
@@ -0,0 +1,117 @@
|
|
|
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 | identifierDotAttribute | 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
|
+
def makeUnRePackDataclass(astImportFrom: ast.ImportFrom, moduleIdentifier: str = identifierModuleDataPackingDEFAULT) -> None:
|
|
69
|
+
"""Generate interface module for dataclass unpacking and repacking operations.
|
|
70
|
+
|
|
71
|
+
Parameters
|
|
72
|
+
----------
|
|
73
|
+
astImportFrom : ast.ImportFrom
|
|
74
|
+
Import statement specifying the target optimized function to call.
|
|
75
|
+
|
|
76
|
+
Returns
|
|
77
|
+
-------
|
|
78
|
+
None
|
|
79
|
+
The generated module is written directly to the filesystem.
|
|
80
|
+
|
|
81
|
+
"""
|
|
82
|
+
callableIdentifierHARDCODED: str = 'sequential'
|
|
83
|
+
|
|
84
|
+
algorithmSourceModule: identifierDotAttribute = identifierModuleSourceAlgorithmDEFAULT
|
|
85
|
+
callableIdentifier: identifierDotAttribute = callableIdentifierHARDCODED
|
|
86
|
+
logicalPathInfix: identifierDotAttribute = logicalPathInfixDEFAULT
|
|
87
|
+
logicalPathInfixAlgorithm: identifierDotAttribute = logicalPathInfixAlgorithmDEFAULT
|
|
88
|
+
sourceCallableIdentifier: identifierDotAttribute = identifierCallableSourceDispatcherDEFAULT
|
|
89
|
+
|
|
90
|
+
logicalPathSourceModule: identifierDotAttribute = '.'.join([packageSettings.identifierPackage, logicalPathInfixAlgorithm, algorithmSourceModule]) # noqa: FLY002
|
|
91
|
+
|
|
92
|
+
ingredientsFunction: IngredientsFunction = astModuleToIngredientsFunction(parseLogicalPath2astModule(logicalPathSourceModule), sourceCallableIdentifier)
|
|
93
|
+
ingredientsFunction.astFunctionDef.name = callableIdentifier
|
|
94
|
+
|
|
95
|
+
shatteredDataclass: ShatteredDataclass = shatter_dataclassesDOTdataclass(*findDataclass(ingredientsFunction))
|
|
96
|
+
|
|
97
|
+
ingredientsFunction.imports.update(shatteredDataclass.imports)
|
|
98
|
+
ingredientsFunction.imports.addAst(astImportFrom)
|
|
99
|
+
targetCallableIdentifier: str = astImportFrom.names[0].name
|
|
100
|
+
ingredientsFunction = raiseIfNone(unpackDataclassCallFunctionRepackDataclass(ingredientsFunction, targetCallableIdentifier, shatteredDataclass))
|
|
101
|
+
targetFunctionDef: ast.FunctionDef = raiseIfNone(extractFunctionDef(parseLogicalPath2astModule(raiseIfNone(astImportFrom.module)), targetCallableIdentifier))
|
|
102
|
+
astTuple: ast.Tuple = cast('ast.Tuple', raiseIfNone(NodeTourist(Be.Return.valueIs(Be.Tuple)
|
|
103
|
+
, doThat=Then.extractIt(DOT.value)).captureLastMatch(targetFunctionDef)))
|
|
104
|
+
astTuple.ctx = Make.Store()
|
|
105
|
+
|
|
106
|
+
changeAssignCallToTarget = NodeChanger(
|
|
107
|
+
findThis = Be.Assign.valueIs(IfThis.isCallIdentifier(targetCallableIdentifier))
|
|
108
|
+
, doThat = Then.replaceWith(Make.Assign([astTuple], value=Make.Call(Make.Name(targetCallableIdentifier), astTuple.elts))))
|
|
109
|
+
changeAssignCallToTarget.visit(ingredientsFunction.astFunctionDef)
|
|
110
|
+
|
|
111
|
+
ingredientsModule = IngredientsModule(ingredientsFunction)
|
|
112
|
+
ingredientsModule.removeImportFromModule('numpy')
|
|
113
|
+
|
|
114
|
+
pathFilename: PurePath = getPathFilename(packageSettings.pathPackage, logicalPathInfix, moduleIdentifier)
|
|
115
|
+
|
|
116
|
+
write_astModule(ingredientsModule, pathFilename, packageSettings.identifierPackage)
|
|
117
|
+
|
|
File without changes
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
"""makeMapFoldingModules."""
|
|
2
|
+
from astToolkit import (
|
|
3
|
+
astModuleToIngredientsFunction, Be, DOT, extractClassDef, Grab, hasDOTbody, identifierDotAttribute,
|
|
4
|
+
IngredientsFunction, IngredientsModule, LedgerOfImports, Make, NodeChanger, NodeTourist, parseLogicalPath2astModule,
|
|
5
|
+
parsePathFilename2astModule, Then)
|
|
6
|
+
from astToolkit.transformationTools import inlineFunctionDef, removeUnusedParameters, write_astModule
|
|
7
|
+
from hunterMakesPy import importLogicalPath2Identifier, raiseIfNone
|
|
8
|
+
from mapFolding import packageSettings
|
|
9
|
+
from mapFolding.someAssemblyRequired import (
|
|
10
|
+
DeReConstructField2ast, identifierCallableSourceDEFAULT, identifierCallableSourceDispatcherDEFAULT, IfThis,
|
|
11
|
+
logicalPathInfixDEFAULT, ShatteredDataclass)
|
|
12
|
+
from mapFolding.someAssemblyRequired.makingModules_count import (
|
|
13
|
+
makeDaoOfMapFoldingNumba, makeTheorem2, numbaOnTheorem2, trimTheorem2)
|
|
14
|
+
from mapFolding.someAssemblyRequired.makingModules_doTheNeedful import makeInitializeState, makeUnRePackDataclass
|
|
15
|
+
from mapFolding.someAssemblyRequired.toolkitMakeModules import getLogicalPath, getModule, 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 Any, TYPE_CHECKING
|
|
22
|
+
import ast
|
|
23
|
+
import dataclasses
|
|
24
|
+
|
|
25
|
+
if TYPE_CHECKING:
|
|
26
|
+
from collections.abc import Sequence
|
|
27
|
+
|
|
28
|
+
def makeDaoOfMapFoldingParallelNumba(astModule: ast.Module, moduleIdentifier: str, callableIdentifier: str | None = None, logicalPathInfix: PathLike[str] | PurePath | str | None = None, sourceCallableDispatcher: str | None = None) -> PurePath: # noqa: ARG001
|
|
29
|
+
"""Generate parallel implementation with concurrent execution and task division.
|
|
30
|
+
|
|
31
|
+
Parameters
|
|
32
|
+
----------
|
|
33
|
+
astModule : ast.Module
|
|
34
|
+
Source module containing the base algorithm.
|
|
35
|
+
moduleIdentifier : str
|
|
36
|
+
Name for the generated parallel module.
|
|
37
|
+
callableIdentifier : str | None = None
|
|
38
|
+
Name for the core parallel counting function.
|
|
39
|
+
logicalPathInfix : PathLike[str] | PurePath | str | None = None
|
|
40
|
+
Directory path for organizing the generated module.
|
|
41
|
+
sourceCallableDispatcher : str | None = None
|
|
42
|
+
Optional dispatcher function identifier.
|
|
43
|
+
|
|
44
|
+
Returns
|
|
45
|
+
-------
|
|
46
|
+
pathFilename : PurePath
|
|
47
|
+
Filesystem path where the parallel module was written.
|
|
48
|
+
|
|
49
|
+
"""
|
|
50
|
+
sourceCallableIdentifier = identifierCallableSourceDEFAULT
|
|
51
|
+
if callableIdentifier is None:
|
|
52
|
+
callableIdentifier = sourceCallableIdentifier
|
|
53
|
+
ingredientsFunction = IngredientsFunction(inlineFunctionDef(sourceCallableIdentifier, astModule), LedgerOfImports(astModule))
|
|
54
|
+
ingredientsFunction.astFunctionDef.name = callableIdentifier
|
|
55
|
+
|
|
56
|
+
dataclassName: ast.expr = raiseIfNone(NodeTourist(Be.arg, Then.extractIt(DOT.annotation)).captureLastMatch(ingredientsFunction.astFunctionDef))
|
|
57
|
+
dataclassIdentifier: str = raiseIfNone(NodeTourist(Be.Name, Then.extractIt(DOT.id)).captureLastMatch(dataclassName))
|
|
58
|
+
|
|
59
|
+
dataclassLogicalPathModule = None
|
|
60
|
+
for moduleWithLogicalPath, listNameTuples in ingredientsFunction.imports._dictionaryImportFrom.items(): # noqa: SLF001
|
|
61
|
+
for nameTuple in listNameTuples:
|
|
62
|
+
if nameTuple[0] == dataclassIdentifier:
|
|
63
|
+
dataclassLogicalPathModule = moduleWithLogicalPath
|
|
64
|
+
break
|
|
65
|
+
if dataclassLogicalPathModule:
|
|
66
|
+
break
|
|
67
|
+
if dataclassLogicalPathModule is None:
|
|
68
|
+
raise Exception # noqa: TRY002
|
|
69
|
+
dataclassInstanceIdentifier: identifierDotAttribute = raiseIfNone(NodeTourist(Be.arg, Then.extractIt(DOT.arg)).captureLastMatch(ingredientsFunction.astFunctionDef))
|
|
70
|
+
shatteredDataclass: ShatteredDataclass = shatter_dataclassesDOTdataclass(dataclassLogicalPathModule, dataclassIdentifier, dataclassInstanceIdentifier)
|
|
71
|
+
|
|
72
|
+
# START add the parallel state fields to the count function ------------------------------------------------
|
|
73
|
+
dataclassBaseFields: tuple[dataclasses.Field[Any], ...] = dataclasses.fields(importLogicalPath2Identifier(dataclassLogicalPathModule, dataclassIdentifier)) # pyright: ignore [reportArgumentType]
|
|
74
|
+
dataclassIdentifierParallel: identifierDotAttribute = 'Parallel' + dataclassIdentifier
|
|
75
|
+
dataclassFieldsParallel: tuple[dataclasses.Field[Any], ...] = dataclasses.fields(importLogicalPath2Identifier(dataclassLogicalPathModule, dataclassIdentifierParallel)) # pyright: ignore [reportArgumentType]
|
|
76
|
+
onlyParallelFields: list[dataclasses.Field[Any]] = [field for field in dataclassFieldsParallel if field.name not in [fieldBase.name for fieldBase in dataclassBaseFields]]
|
|
77
|
+
|
|
78
|
+
Official_fieldOrder: list[str] = []
|
|
79
|
+
dictionaryDeReConstruction: dict[str, DeReConstructField2ast] = {}
|
|
80
|
+
|
|
81
|
+
dataclassClassDef: ast.ClassDef | None = extractClassDef(parseLogicalPath2astModule(dataclassLogicalPathModule), dataclassIdentifierParallel)
|
|
82
|
+
if not dataclassClassDef:
|
|
83
|
+
message = f"I could not find `{dataclassIdentifierParallel = }` in `{dataclassLogicalPathModule = }`."
|
|
84
|
+
raise ValueError(message)
|
|
85
|
+
|
|
86
|
+
for aField in onlyParallelFields:
|
|
87
|
+
Official_fieldOrder.append(aField.name)
|
|
88
|
+
dictionaryDeReConstruction[aField.name] = DeReConstructField2ast(dataclassLogicalPathModule, dataclassClassDef, dataclassInstanceIdentifier, aField)
|
|
89
|
+
|
|
90
|
+
shatteredDataclassParallel = ShatteredDataclass(
|
|
91
|
+
countingVariableAnnotation=shatteredDataclass.countingVariableAnnotation,
|
|
92
|
+
countingVariableName=shatteredDataclass.countingVariableName,
|
|
93
|
+
field2AnnAssign={**shatteredDataclass.field2AnnAssign, **{dictionaryDeReConstruction[field].name: dictionaryDeReConstruction[field].astAnnAssignConstructor for field in Official_fieldOrder}},
|
|
94
|
+
Z0Z_field2AnnAssign={**shatteredDataclass.Z0Z_field2AnnAssign, **{dictionaryDeReConstruction[field].name: dictionaryDeReConstruction[field].Z0Z_hack for field in Official_fieldOrder}},
|
|
95
|
+
list_argAnnotated4ArgumentsSpecification=shatteredDataclass.list_argAnnotated4ArgumentsSpecification + [dictionaryDeReConstruction[field].ast_argAnnotated for field in Official_fieldOrder],
|
|
96
|
+
list_keyword_field__field4init=shatteredDataclass.list_keyword_field__field4init + [dictionaryDeReConstruction[field].ast_keyword_field__field for field in Official_fieldOrder if dictionaryDeReConstruction[field].init],
|
|
97
|
+
listAnnotations=shatteredDataclass.listAnnotations + [dictionaryDeReConstruction[field].astAnnotation for field in Official_fieldOrder],
|
|
98
|
+
listName4Parameters=shatteredDataclass.listName4Parameters + [dictionaryDeReConstruction[field].astName for field in Official_fieldOrder],
|
|
99
|
+
listUnpack=shatteredDataclass.listUnpack + [Make.AnnAssign(dictionaryDeReConstruction[field].astName, dictionaryDeReConstruction[field].astAnnotation, dictionaryDeReConstruction[field].ast_nameDOTname) for field in Official_fieldOrder],
|
|
100
|
+
map_stateDOTfield2Name={**shatteredDataclass.map_stateDOTfield2Name, **{dictionaryDeReConstruction[field].ast_nameDOTname: dictionaryDeReConstruction[field].astName for field in Official_fieldOrder}},
|
|
101
|
+
)
|
|
102
|
+
shatteredDataclassParallel.fragments4AssignmentOrParameters = Make.Tuple(shatteredDataclassParallel.listName4Parameters, Make.Store())
|
|
103
|
+
shatteredDataclassParallel.repack = Make.Assign([Make.Name(dataclassInstanceIdentifier)], value=Make.Call(Make.Name(dataclassIdentifierParallel), list_keyword=shatteredDataclassParallel.list_keyword_field__field4init))
|
|
104
|
+
shatteredDataclassParallel.signatureReturnAnnotation = Make.Subscript(Make.Name('tuple'), Make.Tuple(shatteredDataclassParallel.listAnnotations))
|
|
105
|
+
|
|
106
|
+
shatteredDataclassParallel.imports.update(*(dictionaryDeReConstruction[field].ledger for field in Official_fieldOrder))
|
|
107
|
+
shatteredDataclassParallel.imports.addImportFrom_asStr(dataclassLogicalPathModule, dataclassIdentifierParallel)
|
|
108
|
+
shatteredDataclassParallel.imports.update(shatteredDataclass.imports)
|
|
109
|
+
shatteredDataclassParallel.imports.removeImportFrom(dataclassLogicalPathModule, dataclassIdentifier)
|
|
110
|
+
|
|
111
|
+
# END add the parallel state fields to the count function ------------------------------------------------
|
|
112
|
+
|
|
113
|
+
ingredientsFunction.imports.update(shatteredDataclassParallel.imports)
|
|
114
|
+
ingredientsFunction: IngredientsFunction = removeDataclassFromFunction(ingredientsFunction, shatteredDataclassParallel)
|
|
115
|
+
|
|
116
|
+
# START add the parallel logic to the count function ------------------------------------------------
|
|
117
|
+
|
|
118
|
+
findThis = Be.While.testIs(Be.Compare.leftIs(IfThis.isNameIdentifier('leafConnectee')))
|
|
119
|
+
captureCountGapsCodeBlock: NodeTourist[ast.While, Sequence[ast.stmt]] = NodeTourist(findThis, doThat = Then.extractIt(DOT.body))
|
|
120
|
+
countGapsCodeBlock: Sequence[ast.stmt] = raiseIfNone(captureCountGapsCodeBlock.captureLastMatch(ingredientsFunction.astFunctionDef))
|
|
121
|
+
|
|
122
|
+
thisIsMyTaskIndexCodeBlock = ast.If(ast.BoolOp(ast.Or()
|
|
123
|
+
, values=[ast.Compare(ast.Name('leaf1ndex'), ops=[ast.NotEq()], comparators=[ast.Name('taskDivisions')])
|
|
124
|
+
, ast.Compare(Make.Mod.join([ast.Name('leafConnectee'), ast.Name('taskDivisions')]), ops=[ast.Eq()], comparators=[ast.Name('taskIndex')])])
|
|
125
|
+
, body=list(countGapsCodeBlock[0:-1]))
|
|
126
|
+
|
|
127
|
+
countGapsCodeBlockNew: list[ast.stmt] = [thisIsMyTaskIndexCodeBlock, countGapsCodeBlock[-1]]
|
|
128
|
+
NodeChanger[ast.While, hasDOTbody](findThis, doThat = Grab.bodyAttribute(Then.replaceWith(countGapsCodeBlockNew))).visit(ingredientsFunction.astFunctionDef)
|
|
129
|
+
|
|
130
|
+
# END add the parallel logic to the count function ------------------------------------------------
|
|
131
|
+
|
|
132
|
+
ingredientsFunction = removeUnusedParameters(ingredientsFunction)
|
|
133
|
+
|
|
134
|
+
ingredientsFunction = decorateCallableWithNumba(ingredientsFunction, parametersNumbaLight)
|
|
135
|
+
|
|
136
|
+
# START unpack/repack the dataclass function ------------------------------------------------
|
|
137
|
+
sourceCallableIdentifier = identifierCallableSourceDispatcherDEFAULT
|
|
138
|
+
|
|
139
|
+
unRepackDataclass: IngredientsFunction = astModuleToIngredientsFunction(astModule, sourceCallableIdentifier)
|
|
140
|
+
unRepackDataclass.astFunctionDef.name = 'unRepack' + dataclassIdentifierParallel
|
|
141
|
+
unRepackDataclass.imports.update(shatteredDataclassParallel.imports)
|
|
142
|
+
NodeChanger(
|
|
143
|
+
findThis = Be.arg.annotationIs(Be.Name.idIs(lambda thisAttribute: thisAttribute == dataclassIdentifier)) # pyright: ignore[reportArgumentType]
|
|
144
|
+
, doThat = Grab.annotationAttribute(Grab.idAttribute(Then.replaceWith(dataclassIdentifierParallel)))
|
|
145
|
+
).visit(unRepackDataclass.astFunctionDef)
|
|
146
|
+
unRepackDataclass.astFunctionDef.returns = Make.Name(dataclassIdentifierParallel)
|
|
147
|
+
targetCallableIdentifier: identifierDotAttribute = ingredientsFunction.astFunctionDef.name
|
|
148
|
+
unRepackDataclass = unpackDataclassCallFunctionRepackDataclass(unRepackDataclass, targetCallableIdentifier, shatteredDataclassParallel)
|
|
149
|
+
|
|
150
|
+
astTuple: ast.Tuple = raiseIfNone(NodeTourist[ast.Return, ast.Tuple](Be.Return, Then.extractIt(DOT.value)).captureLastMatch(ingredientsFunction.astFunctionDef)) # pyright: ignore[reportArgumentType]
|
|
151
|
+
astTuple.ctx = Make.Store()
|
|
152
|
+
changeAssignCallToTarget: NodeChanger[ast.Assign, ast.Assign] = NodeChanger(
|
|
153
|
+
findThis = Be.Assign.valueIs(IfThis.isCallIdentifier(targetCallableIdentifier))
|
|
154
|
+
, doThat = Then.replaceWith(Make.Assign([astTuple], value=Make.Call(Make.Name(targetCallableIdentifier), astTuple.elts)))
|
|
155
|
+
)
|
|
156
|
+
changeAssignCallToTarget.visit(unRepackDataclass.astFunctionDef)
|
|
157
|
+
|
|
158
|
+
ingredientsDoTheNeedful: IngredientsFunction = IngredientsFunction(
|
|
159
|
+
astFunctionDef = Make.FunctionDef('doTheNeedful'
|
|
160
|
+
, argumentSpecification=Make.arguments(list_arg=[Make.arg('state', annotation=Make.Name(dataclassIdentifierParallel)), Make.arg('concurrencyLimit', annotation=Make.Name('int'))])
|
|
161
|
+
, body=[Make.Assign([Make.Name('stateParallel', Make.Store())], value=Make.Call(Make.Name('deepcopy'), listParameters=[Make.Name('state')]))
|
|
162
|
+
, Make.AnnAssign(Make.Name('listStatesParallel', Make.Store()), annotation=Make.Subscript(value=Make.Name('list'), slice=Make.Name(dataclassIdentifierParallel))
|
|
163
|
+
, value=Make.Mult.join([Make.List([Make.Name('stateParallel')]), Make.Attribute(Make.Name('stateParallel'), 'taskDivisions')]))
|
|
164
|
+
, Make.AnnAssign(Make.Name('groupsOfFoldsTotal', Make.Store()), annotation=Make.Name('int'), value=Make.Constant(value=0))
|
|
165
|
+
|
|
166
|
+
, Make.AnnAssign(Make.Name('dictionaryConcurrency', Make.Store()), annotation=Make.Subscript(value=Make.Name('dict'), slice=Make.Tuple([Make.Name('int'), Make.Subscript(value=Make.Name('ConcurrentFuture'), slice=Make.Name(dataclassIdentifierParallel))])), value=Make.Dict())
|
|
167
|
+
, Make.With(items=[Make.withitem(context_expr=Make.Call(Make.Name('ProcessPoolExecutor'), listParameters=[Make.Name('concurrencyLimit')]), optional_vars=Make.Name('concurrencyManager', Make.Store()))]
|
|
168
|
+
, body=[Make.For(Make.Name('indexSherpa', Make.Store()), iter=Make.Call(Make.Name('range'), listParameters=[Make.Attribute(Make.Name('stateParallel'), 'taskDivisions')])
|
|
169
|
+
, body=[Make.Assign([Make.Name('state', Make.Store())], value=Make.Call(Make.Name('deepcopy'), listParameters=[Make.Name('stateParallel')]))
|
|
170
|
+
, Make.Assign([Make.Attribute(Make.Name('state'), 'taskIndex', context=Make.Store())], value=Make.Name('indexSherpa'))
|
|
171
|
+
, Make.Assign([Make.Subscript(Make.Name('dictionaryConcurrency'), slice=Make.Name('indexSherpa'), context=Make.Store())], value=Make.Call(Make.Attribute(Make.Name('concurrencyManager'), 'submit'), listParameters=[Make.Name(unRepackDataclass.astFunctionDef.name), Make.Name('state')]))])
|
|
172
|
+
, Make.For(Make.Name('indexSherpa', Make.Store()), iter=Make.Call(Make.Name('range'), listParameters=[Make.Attribute(Make.Name('stateParallel'), 'taskDivisions')])
|
|
173
|
+
, body=[Make.Assign([Make.Subscript(Make.Name('listStatesParallel'), slice=Make.Name('indexSherpa'), context=Make.Store())], value=Make.Call(Make.Attribute(Make.Subscript(Make.Name('dictionaryConcurrency'), slice=Make.Name('indexSherpa')), 'result')))
|
|
174
|
+
, Make.AugAssign(Make.Name('groupsOfFoldsTotal', Make.Store()), op=ast.Add(), value=Make.Attribute(Make.Subscript(Make.Name('listStatesParallel'), slice=Make.Name('indexSherpa')), 'groupsOfFolds'))])])
|
|
175
|
+
|
|
176
|
+
, Make.AnnAssign(Make.Name('foldsTotal', Make.Store()), annotation=Make.Name('int'), value=Make.Mult.join([Make.Name('groupsOfFoldsTotal'), Make.Attribute(Make.Name('stateParallel'), 'leavesTotal')]))
|
|
177
|
+
, Make.Return(Make.Tuple([Make.Name('foldsTotal'), Make.Name('listStatesParallel')]))]
|
|
178
|
+
, returns=Make.Subscript(Make.Name('tuple'), slice=Make.Tuple([Make.Name('int'), Make.Subscript(Make.Name('list'), slice=Make.Name(dataclassIdentifierParallel))])))
|
|
179
|
+
, imports = LedgerOfImports(Make.Module([Make.ImportFrom('concurrent.futures', list_alias=[Make.alias('Future', asName='ConcurrentFuture'), Make.alias('ProcessPoolExecutor')]),
|
|
180
|
+
Make.ImportFrom('copy', list_alias=[Make.alias('deepcopy')]),
|
|
181
|
+
Make.ImportFrom('multiprocessing', list_alias=[Make.alias('set_start_method', asName='multiprocessing_set_start_method')])])
|
|
182
|
+
)
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
ingredientsModule = IngredientsModule([ingredientsFunction, unRepackDataclass, ingredientsDoTheNeedful]
|
|
186
|
+
, prologue = Make.Module([Make.If(test=Make.Compare(left=Make.Name('__name__'), ops=[Make.Eq()], comparators=[Make.Constant('__main__')]), body=[Make.Expr(Make.Call(Make.Name('multiprocessing_set_start_method'), listParameters=[Make.Constant('spawn')]))])])
|
|
187
|
+
)
|
|
188
|
+
ingredientsModule.removeImportFromModule('numpy')
|
|
189
|
+
|
|
190
|
+
pathFilename: PurePath = getPathFilename(packageSettings.pathPackage, logicalPathInfix, moduleIdentifier)
|
|
191
|
+
|
|
192
|
+
write_astModule(ingredientsModule, pathFilename, packageSettings.identifierPackage)
|
|
193
|
+
|
|
194
|
+
return pathFilename
|
|
195
|
+
|
|
196
|
+
def makeMapFoldingModules() -> None:
|
|
197
|
+
"""Make multidimensional map folding modules."""
|
|
198
|
+
astModule = getModule(logicalPathInfix='algorithms')
|
|
199
|
+
pathFilename: PurePath = makeDaoOfMapFoldingNumba(astModule, 'daoOfMapFoldingNumba', None, logicalPathInfixDEFAULT, identifierCallableSourceDispatcherDEFAULT)
|
|
200
|
+
|
|
201
|
+
astModule = getModule(logicalPathInfix='algorithms')
|
|
202
|
+
pathFilename = makeDaoOfMapFoldingParallelNumba(astModule, 'countParallelNumba', None, logicalPathInfixDEFAULT, identifierCallableSourceDispatcherDEFAULT)
|
|
203
|
+
|
|
204
|
+
astModule: ast.Module = getModule(logicalPathInfix='algorithms')
|
|
205
|
+
makeInitializeState(astModule, 'initializeState', 'transitionOnGroupsOfFolds', logicalPathInfixDEFAULT)
|
|
206
|
+
|
|
207
|
+
astModule = getModule(logicalPathInfix='algorithms')
|
|
208
|
+
pathFilename = makeTheorem2(astModule, 'theorem2', None, logicalPathInfixDEFAULT, None)
|
|
209
|
+
|
|
210
|
+
astModule = parsePathFilename2astModule(pathFilename)
|
|
211
|
+
pathFilename = trimTheorem2(astModule, 'theorem2Trimmed', None, logicalPathInfixDEFAULT, None)
|
|
212
|
+
|
|
213
|
+
astModule = parsePathFilename2astModule(pathFilename)
|
|
214
|
+
pathFilename = numbaOnTheorem2(astModule, 'theorem2Numba', None, logicalPathInfixDEFAULT, None)
|
|
215
|
+
|
|
216
|
+
astImportFrom: ast.ImportFrom = Make.ImportFrom(getLogicalPath(packageSettings.identifierPackage, logicalPathInfixDEFAULT, 'theorem2Numba'), list_alias=[Make.alias(identifierCallableSourceDEFAULT)])
|
|
217
|
+
makeUnRePackDataclass(astImportFrom)
|
|
218
|
+
|
|
219
|
+
if __name__ == '__main__':
|
|
220
|
+
makeMapFoldingModules()
|
|
File without changes
|