mapFolding 0.9.0__py3-none-any.whl → 0.9.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.
- mapFolding/beDRY.py +1 -2
- mapFolding/oeis.py +20 -14
- mapFolding/someAssemblyRequired/RecipeJob.py +103 -0
- mapFolding/someAssemblyRequired/__init__.py +29 -29
- mapFolding/someAssemblyRequired/_tool_Make.py +1 -1
- mapFolding/someAssemblyRequired/_toolboxAntecedents.py +12 -0
- mapFolding/someAssemblyRequired/_toolboxContainers.py +27 -27
- mapFolding/someAssemblyRequired/_toolboxPython.py +3 -0
- mapFolding/someAssemblyRequired/synthesizeNumbaJob.py +58 -26
- mapFolding/someAssemblyRequired/toolboxNumba.py +19 -212
- mapFolding/someAssemblyRequired/transformationTools.py +154 -7
- mapFolding/syntheticModules/{numbaCount_doTheNeedful.py → numbaCount.py} +7 -4
- mapFolding/theDao.py +19 -16
- mapFolding/theSSOT.py +19 -9
- {mapfolding-0.9.0.dist-info → mapfolding-0.9.1.dist-info}/METADATA +1 -1
- {mapfolding-0.9.0.dist-info → mapfolding-0.9.1.dist-info}/RECORD +21 -20
- tests/test_computations.py +2 -1
- {mapfolding-0.9.0.dist-info → mapfolding-0.9.1.dist-info}/WHEEL +0 -0
- {mapfolding-0.9.0.dist-info → mapfolding-0.9.1.dist-info}/entry_points.txt +0 -0
- {mapfolding-0.9.0.dist-info → mapfolding-0.9.1.dist-info}/licenses/LICENSE +0 -0
- {mapfolding-0.9.0.dist-info → mapfolding-0.9.1.dist-info}/top_level.txt +0 -0
|
@@ -16,13 +16,10 @@ performance improvements while preserving code semantics and correctness.
|
|
|
16
16
|
"""
|
|
17
17
|
|
|
18
18
|
from collections.abc import Callable, Sequence
|
|
19
|
-
from mapFolding.someAssemblyRequired import
|
|
20
|
-
from mapFolding.someAssemblyRequired.transformationTools import
|
|
21
|
-
from mapFolding.theSSOT import ComputationState, DatatypeFoldsTotal as TheDatatypeFoldsTotal, DatatypeElephino as TheDatatypeElephino, DatatypeLeavesTotal as TheDatatypeLeavesTotal
|
|
22
|
-
from mapFolding.toolboxFilesystem import getPathFilenameFoldsTotal, getPathRootJobDEFAULT
|
|
19
|
+
from mapFolding.someAssemblyRequired import Make, NodeTourist, RecipeSynthesizeFlow, Then, ast_Identifier, str_nameDOTname, IngredientsFunction
|
|
20
|
+
from mapFolding.someAssemblyRequired.transformationTools import ( makeNewFlow, write_astModule, )
|
|
23
21
|
from numba.core.compiler import CompilerBase as numbaCompilerBase
|
|
24
|
-
from
|
|
25
|
-
from typing import Any, cast, Final, TYPE_CHECKING, TypeAlias, TypeGuard
|
|
22
|
+
from typing import Any, cast, Final, TYPE_CHECKING, TypeGuard
|
|
26
23
|
import ast
|
|
27
24
|
import dataclasses
|
|
28
25
|
|
|
@@ -48,17 +45,17 @@ class ParametersNumba(TypedDict):
|
|
|
48
45
|
debug: NotRequired[bool]
|
|
49
46
|
error_model: str
|
|
50
47
|
fastmath: bool
|
|
51
|
-
forceinline: bool
|
|
48
|
+
forceinline: NotRequired[bool]
|
|
52
49
|
forceobj: NotRequired[bool]
|
|
53
|
-
inline: str
|
|
50
|
+
inline: NotRequired[str]
|
|
54
51
|
locals: NotRequired[dict[str, Any]]
|
|
55
|
-
looplift: bool
|
|
56
|
-
no_cfunc_wrapper: bool
|
|
57
|
-
no_cpython_wrapper: bool
|
|
52
|
+
looplift: NotRequired[bool]
|
|
53
|
+
no_cfunc_wrapper: NotRequired[bool]
|
|
54
|
+
no_cpython_wrapper: NotRequired[bool]
|
|
58
55
|
no_rewrites: NotRequired[bool]
|
|
59
56
|
nogil: NotRequired[bool]
|
|
60
|
-
nopython: bool
|
|
61
|
-
parallel: bool
|
|
57
|
+
nopython: NotRequired[bool]
|
|
58
|
+
parallel: NotRequired[bool]
|
|
62
59
|
pipeline_class: NotRequired[type[numbaCompilerBase]]
|
|
63
60
|
signature_or_function: NotRequired[Any | Callable[..., Any] | str | tuple[Any, ...]]
|
|
64
61
|
target: NotRequired[str]
|
|
@@ -74,6 +71,7 @@ parametersNumbaSuperJit: Final[ParametersNumba] = { **parametersNumbaDefault, 'n
|
|
|
74
71
|
parametersNumbaSuperJitParallel: Final[ParametersNumba] = { **parametersNumbaSuperJit, '_nrt': True, 'parallel': True, }
|
|
75
72
|
"""Speed, no helmet, concurrency, no talking to non-jitted functions."""
|
|
76
73
|
parametersNumbaMinimum: Final[ParametersNumba] = { '_nrt': True, 'boundscheck': True, 'cache': True, 'error_model': 'numpy', 'fastmath': True, 'forceinline': False, 'inline': 'always', 'looplift': False, 'no_cfunc_wrapper': False, 'no_cpython_wrapper': False, 'nopython': False, 'forceobj': True, 'parallel': False, }
|
|
74
|
+
parametersNumbaLight: Final[ParametersNumba] = {'cache': True, 'error_model': 'numpy', 'fastmath': True, 'forceinline': True}
|
|
77
75
|
|
|
78
76
|
Z0Z_numbaDataTypeModule: str_nameDOTname = 'numba'
|
|
79
77
|
Z0Z_decoratorCallable: ast_Identifier = 'jit'
|
|
@@ -121,10 +119,10 @@ def decorateCallableWithNumba(ingredientsFunction: IngredientsFunction, paramete
|
|
|
121
119
|
list_arg4signature_or_function: list[ast.expr] = []
|
|
122
120
|
for parameter in ingredientsFunction.astFunctionDef.args.args:
|
|
123
121
|
# For now, let Numba infer them.
|
|
122
|
+
signatureElement: ast.Subscript | ast.Name | None = makeSpecialSignatureForNumba(parameter)
|
|
123
|
+
if signatureElement:
|
|
124
|
+
list_arg4signature_or_function.append(signatureElement)
|
|
124
125
|
continue
|
|
125
|
-
# signatureElement: ast.Subscript | ast.Name | None = makeSpecialSignatureForNumba(parameter)
|
|
126
|
-
# if signatureElement:
|
|
127
|
-
# list_arg4signature_or_function.append(signatureElement)
|
|
128
126
|
|
|
129
127
|
if ingredientsFunction.astFunctionDef.returns and isinstance(ingredientsFunction.astFunctionDef.returns, ast.Name):
|
|
130
128
|
theReturn: ast.Name = ingredientsFunction.astFunctionDef.returns
|
|
@@ -153,103 +151,9 @@ def decorateCallableWithNumba(ingredientsFunction: IngredientsFunction, paramete
|
|
|
153
151
|
class SpicesJobNumba:
|
|
154
152
|
useNumbaProgressBar: bool = True
|
|
155
153
|
numbaProgressBarIdentifier: ast_Identifier = 'ProgressBarGroupsOfFolds'
|
|
156
|
-
parametersNumba =
|
|
154
|
+
parametersNumba: ParametersNumba = dataclasses.field(default_factory=ParametersNumba) # type: ignore
|
|
157
155
|
|
|
158
156
|
# Consolidate settings classes through inheritance https://github.com/hunterhogan/mapFolding/issues/15
|
|
159
|
-
@dataclasses.dataclass
|
|
160
|
-
class RecipeJob:
|
|
161
|
-
state: ComputationState
|
|
162
|
-
# TODO create function to calculate `foldsTotalEstimated`
|
|
163
|
-
foldsTotalEstimated: int = 0
|
|
164
|
-
shatteredDataclass: ShatteredDataclass = dataclasses.field(default=None, init=True) # pyright: ignore[reportAssignmentType]
|
|
165
|
-
|
|
166
|
-
# ========================================
|
|
167
|
-
# Source
|
|
168
|
-
source_astModule = parsePathFilename2astModule(theNumbaFlow.pathFilenameSequential)
|
|
169
|
-
sourceCountCallable: ast_Identifier = theNumbaFlow.callableSequential
|
|
170
|
-
|
|
171
|
-
sourceLogicalPathModuleDataclass: str_nameDOTname = theNumbaFlow.logicalPathModuleDataclass
|
|
172
|
-
sourceDataclassIdentifier: ast_Identifier = theNumbaFlow.dataclassIdentifier
|
|
173
|
-
sourceDataclassInstance: ast_Identifier = theNumbaFlow.dataclassInstance
|
|
174
|
-
|
|
175
|
-
sourcePathPackage: PurePosixPath | None = theNumbaFlow.pathPackage
|
|
176
|
-
sourcePackageIdentifier: ast_Identifier | None = theNumbaFlow.packageIdentifier
|
|
177
|
-
|
|
178
|
-
# ========================================
|
|
179
|
-
# Filesystem (names of physical objects)
|
|
180
|
-
pathPackage: PurePosixPath | None = None
|
|
181
|
-
pathModule: PurePosixPath | None = PurePosixPath(getPathRootJobDEFAULT())
|
|
182
|
-
""" `pathModule` will override `pathPackage` and `logicalPathRoot`."""
|
|
183
|
-
fileExtension: str = theNumbaFlow.fileExtension
|
|
184
|
-
pathFilenameFoldsTotal: PurePosixPath = dataclasses.field(default=None, init=True) # pyright: ignore[reportAssignmentType]
|
|
185
|
-
|
|
186
|
-
# ========================================
|
|
187
|
-
# Logical identifiers (as opposed to physical identifiers)
|
|
188
|
-
packageIdentifier: ast_Identifier | None = None
|
|
189
|
-
logicalPathRoot: str_nameDOTname | None = None
|
|
190
|
-
""" `logicalPathRoot` likely corresponds to a physical filesystem directory."""
|
|
191
|
-
moduleIdentifier: ast_Identifier = dataclasses.field(default=None, init=True) # pyright: ignore[reportAssignmentType]
|
|
192
|
-
countCallable: ast_Identifier = sourceCountCallable
|
|
193
|
-
dataclassIdentifier: ast_Identifier | None = sourceDataclassIdentifier
|
|
194
|
-
dataclassInstance: ast_Identifier | None = sourceDataclassInstance
|
|
195
|
-
logicalPathModuleDataclass: str_nameDOTname | None = sourceLogicalPathModuleDataclass
|
|
196
|
-
|
|
197
|
-
# ========================================
|
|
198
|
-
# Datatypes
|
|
199
|
-
DatatypeFoldsTotal: TypeAlias = TheDatatypeFoldsTotal
|
|
200
|
-
DatatypeElephino: TypeAlias = TheDatatypeElephino
|
|
201
|
-
DatatypeLeavesTotal: TypeAlias = TheDatatypeLeavesTotal
|
|
202
|
-
|
|
203
|
-
def _makePathFilename(self,
|
|
204
|
-
pathRoot: PurePosixPath | None = None,
|
|
205
|
-
logicalPathINFIX: str_nameDOTname | None = None,
|
|
206
|
-
filenameStem: str | None = None,
|
|
207
|
-
fileExtension: str | None = None,
|
|
208
|
-
) -> PurePosixPath:
|
|
209
|
-
if pathRoot is None:
|
|
210
|
-
pathRoot = self.pathPackage or PurePosixPath(Path.cwd())
|
|
211
|
-
if logicalPathINFIX:
|
|
212
|
-
whyIsThisStillAThing: list[str] = logicalPathINFIX.split('.')
|
|
213
|
-
pathRoot = pathRoot.joinpath(*whyIsThisStillAThing)
|
|
214
|
-
if filenameStem is None:
|
|
215
|
-
filenameStem = self.moduleIdentifier
|
|
216
|
-
if fileExtension is None:
|
|
217
|
-
fileExtension = self.fileExtension
|
|
218
|
-
filename: str = filenameStem + fileExtension
|
|
219
|
-
return pathRoot.joinpath(filename)
|
|
220
|
-
|
|
221
|
-
@property
|
|
222
|
-
def pathFilenameModule(self) -> PurePosixPath:
|
|
223
|
-
if self.pathModule is None:
|
|
224
|
-
return self._makePathFilename()
|
|
225
|
-
else:
|
|
226
|
-
return self._makePathFilename(pathRoot=self.pathModule, logicalPathINFIX=None)
|
|
227
|
-
|
|
228
|
-
def __post_init__(self):
|
|
229
|
-
pathFilenameFoldsTotal = PurePosixPath(getPathFilenameFoldsTotal(self.state.mapShape))
|
|
230
|
-
|
|
231
|
-
if self.moduleIdentifier is None: # pyright: ignore[reportUnnecessaryComparison]
|
|
232
|
-
self.moduleIdentifier = pathFilenameFoldsTotal.stem
|
|
233
|
-
|
|
234
|
-
if self.pathFilenameFoldsTotal is None: # pyright: ignore[reportUnnecessaryComparison]
|
|
235
|
-
self.pathFilenameFoldsTotal = pathFilenameFoldsTotal
|
|
236
|
-
|
|
237
|
-
if self.shatteredDataclass is None and self.logicalPathModuleDataclass and self.dataclassIdentifier and self.dataclassInstance: # pyright: ignore[reportUnnecessaryComparison]
|
|
238
|
-
self.shatteredDataclass = shatter_dataclassesDOTdataclass(self.logicalPathModuleDataclass, self.dataclassIdentifier, self.dataclassInstance)
|
|
239
|
-
|
|
240
|
-
# ========================================
|
|
241
|
-
# Fields you probably don't need =================================
|
|
242
|
-
# Dispatcher =================================
|
|
243
|
-
sourceDispatcherCallable: ast_Identifier = theNumbaFlow.callableDispatcher
|
|
244
|
-
dispatcherCallable: ast_Identifier = sourceDispatcherCallable
|
|
245
|
-
# Parallel counting =================================
|
|
246
|
-
sourceDataclassInstanceTaskDistribution: ast_Identifier = theNumbaFlow.dataclassInstanceTaskDistribution
|
|
247
|
-
sourceConcurrencyManagerNamespace: ast_Identifier = theNumbaFlow.concurrencyManagerNamespace
|
|
248
|
-
sourceConcurrencyManagerIdentifier: ast_Identifier = theNumbaFlow.concurrencyManagerIdentifier
|
|
249
|
-
dataclassInstanceTaskDistribution: ast_Identifier = sourceDataclassInstanceTaskDistribution
|
|
250
|
-
concurrencyManagerNamespace: ast_Identifier = sourceConcurrencyManagerNamespace
|
|
251
|
-
concurrencyManagerIdentifier: ast_Identifier = sourceConcurrencyManagerIdentifier
|
|
252
|
-
|
|
253
157
|
class be:
|
|
254
158
|
@staticmethod
|
|
255
159
|
def Call(node: ast.AST) -> TypeGuard[ast.Call]:
|
|
@@ -283,109 +187,12 @@ def makeNumbaFlow(numbaFlow: RecipeSynthesizeFlow) -> None:
|
|
|
283
187
|
transformation process, including source and target locations,
|
|
284
188
|
function and variable names, and output paths.
|
|
285
189
|
"""
|
|
286
|
-
# TODO a tool to automatically remove unused variables from the ArgumentsSpecification (return, and returns) _might_ be nice.
|
|
287
|
-
# Figure out dynamic flow control to synthesized modules https://github.com/hunterhogan/mapFolding/issues/4
|
|
288
|
-
|
|
289
|
-
listAllIngredientsFunctions = [
|
|
290
|
-
(ingredientsInitialize := astModuleToIngredientsFunction(numbaFlow.source_astModule, numbaFlow.sourceCallableInitialize)),
|
|
291
|
-
(ingredientsParallel := astModuleToIngredientsFunction(numbaFlow.source_astModule, numbaFlow.sourceCallableParallel)),
|
|
292
|
-
(ingredientsSequential := astModuleToIngredientsFunction(numbaFlow.source_astModule, numbaFlow.sourceCallableSequential)),
|
|
293
|
-
(ingredientsDispatcher := astModuleToIngredientsFunction(numbaFlow.source_astModule, numbaFlow.sourceCallableDispatcher)),
|
|
294
|
-
]
|
|
295
|
-
|
|
296
|
-
# Inline functions ========================================================
|
|
297
|
-
# NOTE Replacements statements are based on the identifiers in the _source_, so operate on the source identifiers.
|
|
298
|
-
ingredientsInitialize.astFunctionDef = inlineFunctionDef(numbaFlow.sourceCallableInitialize, numbaFlow.source_astModule)
|
|
299
|
-
ingredientsParallel.astFunctionDef = inlineFunctionDef(numbaFlow.sourceCallableParallel, numbaFlow.source_astModule)
|
|
300
|
-
ingredientsSequential.astFunctionDef = inlineFunctionDef(numbaFlow.sourceCallableSequential, numbaFlow.source_astModule)
|
|
301
|
-
|
|
302
|
-
# assignRecipeIdentifiersToCallable. =============================
|
|
303
|
-
# Consolidate settings classes through inheritance https://github.com/hunterhogan/mapFolding/issues/15
|
|
304
|
-
# How can I use dataclass settings as the SSOT for specific actions? https://github.com/hunterhogan/mapFolding/issues/16
|
|
305
|
-
# NOTE reminder: you are updating these `ast.Name` here (and not in a more general search) because this is a
|
|
306
|
-
# narrow search for `ast.Call` so you won't accidentally replace unrelated `ast.Name`.
|
|
307
|
-
listFindReplace = [(numbaFlow.sourceCallableDispatcher, numbaFlow.callableDispatcher),
|
|
308
|
-
(numbaFlow.sourceCallableInitialize, numbaFlow.callableInitialize),
|
|
309
|
-
(numbaFlow.sourceCallableParallel, numbaFlow.callableParallel),
|
|
310
|
-
(numbaFlow.sourceCallableSequential, numbaFlow.callableSequential),]
|
|
311
|
-
for ingredients in listAllIngredientsFunctions:
|
|
312
|
-
for source_Identifier, recipe_Identifier in listFindReplace:
|
|
313
|
-
updateCallName = NodeChanger(ifThis.isCall_Identifier(source_Identifier), grab.funcAttribute(Then.replaceWith(Make.Name(recipe_Identifier))))
|
|
314
|
-
updateCallName.visit(ingredients.astFunctionDef)
|
|
315
|
-
|
|
316
|
-
ingredientsDispatcher.astFunctionDef.name = numbaFlow.callableDispatcher
|
|
317
|
-
ingredientsInitialize.astFunctionDef.name = numbaFlow.callableInitialize
|
|
318
|
-
ingredientsParallel.astFunctionDef.name = numbaFlow.callableParallel
|
|
319
|
-
ingredientsSequential.astFunctionDef.name = numbaFlow.callableSequential
|
|
320
|
-
|
|
321
|
-
# Assign identifiers per the recipe. ==============================
|
|
322
|
-
listFindReplace = [(numbaFlow.sourceDataclassInstance, numbaFlow.dataclassInstance),
|
|
323
|
-
(numbaFlow.sourceDataclassInstanceTaskDistribution, numbaFlow.dataclassInstanceTaskDistribution),
|
|
324
|
-
(numbaFlow.sourceConcurrencyManagerNamespace, numbaFlow.concurrencyManagerNamespace),]
|
|
325
|
-
for ingredients in listAllIngredientsFunctions:
|
|
326
|
-
for source_Identifier, recipe_Identifier in listFindReplace:
|
|
327
|
-
updateName = NodeChanger(ifThis.isName_Identifier(source_Identifier) , grab.idAttribute(Then.replaceWith(recipe_Identifier)))
|
|
328
|
-
update_arg = NodeChanger(ifThis.isArgument_Identifier(source_Identifier), grab.argAttribute(Then.replaceWith(recipe_Identifier)))
|
|
329
|
-
updateName.visit(ingredients.astFunctionDef)
|
|
330
|
-
update_arg.visit(ingredients.astFunctionDef)
|
|
331
|
-
|
|
332
|
-
updateConcurrencyManager = NodeChanger(ifThis.isCallAttributeNamespace_Identifier(numbaFlow.sourceConcurrencyManagerNamespace, numbaFlow.sourceConcurrencyManagerIdentifier)
|
|
333
|
-
, grab.funcAttribute(Then.replaceWith(Make.Attribute(Make.Name(numbaFlow.concurrencyManagerNamespace), numbaFlow.concurrencyManagerIdentifier))))
|
|
334
|
-
updateConcurrencyManager.visit(ingredientsDispatcher.astFunctionDef)
|
|
335
|
-
|
|
336
|
-
# shatter Dataclass =======================================================
|
|
337
|
-
instance_Identifier = numbaFlow.dataclassInstance
|
|
338
|
-
getTheOtherRecord_damn = numbaFlow.dataclassInstanceTaskDistribution
|
|
339
|
-
shatteredDataclass = shatter_dataclassesDOTdataclass(numbaFlow.logicalPathModuleDataclass, numbaFlow.sourceDataclassIdentifier, instance_Identifier)
|
|
340
|
-
ingredientsDispatcher.imports.update(shatteredDataclass.ledger)
|
|
341
|
-
|
|
342
|
-
# How can I use dataclass settings as the SSOT for specific actions? https://github.com/hunterhogan/mapFolding/issues/16
|
|
343
|
-
# Change callable parameters and Call to the callable at the same time ====
|
|
344
|
-
# sequentialCallable =========================================================
|
|
345
|
-
ingredientsSequential.astFunctionDef.args = Make.argumentsSpecification(args=shatteredDataclass.list_argAnnotated4ArgumentsSpecification)
|
|
346
|
-
astCallSequentialCallable = Make.Call(Make.Name(numbaFlow.callableSequential), shatteredDataclass.listName4Parameters)
|
|
347
|
-
changeReturnSequentialCallable = NodeChanger(be.Return, Then.replaceWith(Make.Return(shatteredDataclass.fragments4AssignmentOrParameters)))
|
|
348
|
-
ingredientsSequential.astFunctionDef.returns = shatteredDataclass.signatureReturnAnnotation
|
|
349
|
-
replaceAssignSequentialCallable = NodeChanger(ifThis.isAssignAndValueIs(ifThis.isCall_Identifier(numbaFlow.callableSequential)), Then.replaceWith(Make.Assign(listTargets=[shatteredDataclass.fragments4AssignmentOrParameters], value=astCallSequentialCallable)))
|
|
350
|
-
|
|
351
|
-
unpack4sequentialCallable = NodeChanger(ifThis.isAssignAndValueIs(ifThis.isCall_Identifier(numbaFlow.callableSequential)), Then.insertThisAbove(shatteredDataclass.listUnpack))
|
|
352
|
-
repack4sequentialCallable = NodeChanger(ifThis.isAssignAndValueIs(ifThis.isCall_Identifier(numbaFlow.callableSequential)), Then.insertThisBelow([shatteredDataclass.repack]))
|
|
353
|
-
|
|
354
|
-
changeReturnSequentialCallable.visit(ingredientsSequential.astFunctionDef)
|
|
355
|
-
replaceAssignSequentialCallable.visit(ingredientsDispatcher.astFunctionDef)
|
|
356
|
-
unpack4sequentialCallable.visit(ingredientsDispatcher.astFunctionDef)
|
|
357
|
-
repack4sequentialCallable.visit(ingredientsDispatcher.astFunctionDef)
|
|
358
|
-
|
|
359
|
-
ingredientsSequential.astFunctionDef = Z0Z_lameFindReplace(ingredientsSequential.astFunctionDef, shatteredDataclass.map_stateDOTfield2Name)
|
|
360
|
-
|
|
361
|
-
# parallelCallable =========================================================
|
|
362
|
-
ingredientsParallel.astFunctionDef.args = Make.argumentsSpecification(args=shatteredDataclass.list_argAnnotated4ArgumentsSpecification)
|
|
363
|
-
replaceCall2concurrencyManager = NodeChanger(ifThis.isCallAttributeNamespace_Identifier(numbaFlow.concurrencyManagerNamespace, numbaFlow.concurrencyManagerIdentifier), Then.replaceWith(Make.Call(Make.Attribute(Make.Name(numbaFlow.concurrencyManagerNamespace), numbaFlow.concurrencyManagerIdentifier), listArguments=[Make.Name(numbaFlow.callableParallel)] + shatteredDataclass.listName4Parameters)))
|
|
364
|
-
|
|
365
|
-
# NOTE I am dissatisfied with this logic for many reasons, including that it requires separate NodeCollector and NodeReplacer instances.
|
|
366
|
-
astCallConcurrencyResult: list[ast.Call] = []
|
|
367
|
-
get_astCallConcurrencyResult = NodeTourist(ifThis.isAssignAndTargets0Is(ifThis.isSubscript_Identifier(getTheOtherRecord_damn)), getIt(astCallConcurrencyResult))
|
|
368
|
-
get_astCallConcurrencyResult.visit(ingredientsDispatcher.astFunctionDef)
|
|
369
|
-
replaceAssignParallelCallable = NodeChanger(ifThis.isAssignAndTargets0Is(ifThis.isSubscript_Identifier(getTheOtherRecord_damn)), grab.valueAttribute(Then.replaceWith(astCallConcurrencyResult[0])))
|
|
370
|
-
replaceAssignParallelCallable.visit(ingredientsDispatcher.astFunctionDef)
|
|
371
|
-
changeReturnParallelCallable = NodeChanger(be.Return, Then.replaceWith(Make.Return(shatteredDataclass.countingVariableName)))
|
|
372
|
-
ingredientsParallel.astFunctionDef.returns = shatteredDataclass.countingVariableAnnotation
|
|
373
|
-
|
|
374
|
-
unpack4parallelCallable = NodeChanger(ifThis.isAssignAndValueIs(ifThis.isCallAttributeNamespace_Identifier(numbaFlow.concurrencyManagerNamespace, numbaFlow.concurrencyManagerIdentifier)), Then.insertThisAbove(shatteredDataclass.listUnpack))
|
|
375
|
-
|
|
376
|
-
unpack4parallelCallable.visit(ingredientsDispatcher.astFunctionDef)
|
|
377
|
-
replaceCall2concurrencyManager.visit(ingredientsDispatcher.astFunctionDef)
|
|
378
|
-
changeReturnParallelCallable.visit(ingredientsParallel.astFunctionDef)
|
|
379
|
-
|
|
380
|
-
ingredientsParallel.astFunctionDef = Z0Z_lameFindReplace(ingredientsParallel.astFunctionDef, shatteredDataclass.map_stateDOTfield2Name)
|
|
381
190
|
|
|
382
|
-
|
|
383
|
-
ingredientsParallel = decorateCallableWithNumba(ingredientsParallel)
|
|
384
|
-
ingredientsSequential = decorateCallableWithNumba(ingredientsSequential)
|
|
191
|
+
ingredientsModuleNumbaUnified = makeNewFlow(numbaFlow)
|
|
385
192
|
|
|
386
|
-
#
|
|
387
|
-
ingredientsModuleNumbaUnified =
|
|
388
|
-
ingredientsModuleNumbaUnified.
|
|
193
|
+
# numba decorators =========================================
|
|
194
|
+
ingredientsModuleNumbaUnified.listIngredientsFunctions[1] = decorateCallableWithNumba(ingredientsModuleNumbaUnified.listIngredientsFunctions[1])
|
|
195
|
+
ingredientsModuleNumbaUnified.listIngredientsFunctions[2] = decorateCallableWithNumba(ingredientsModuleNumbaUnified.listIngredientsFunctions[2])
|
|
389
196
|
|
|
390
197
|
write_astModule(ingredientsModuleNumbaUnified, numbaFlow.pathFilenameDispatcher, numbaFlow.packageIdentifier)
|
|
391
198
|
|
|
@@ -25,7 +25,9 @@ from mapFolding.beDRY import outfitCountFolds
|
|
|
25
25
|
from mapFolding.toolboxFilesystem import getPathFilenameFoldsTotal, writeStringToHere
|
|
26
26
|
from mapFolding.someAssemblyRequired import (
|
|
27
27
|
ast_Identifier,
|
|
28
|
+
be,
|
|
28
29
|
DOT,
|
|
30
|
+
grab,
|
|
29
31
|
ifThis,
|
|
30
32
|
importLogicalPath2Callable,
|
|
31
33
|
IngredientsFunction,
|
|
@@ -35,6 +37,7 @@ from mapFolding.someAssemblyRequired import (
|
|
|
35
37
|
NodeChanger,
|
|
36
38
|
NodeTourist,
|
|
37
39
|
parseLogicalPath2astModule,
|
|
40
|
+
RecipeSynthesizeFlow,
|
|
38
41
|
ShatteredDataclass,
|
|
39
42
|
str_nameDOTname,
|
|
40
43
|
Then,
|
|
@@ -47,6 +50,7 @@ from typing import Any, Literal, overload
|
|
|
47
50
|
import ast
|
|
48
51
|
import dataclasses
|
|
49
52
|
import pickle
|
|
53
|
+
import python_minifier
|
|
50
54
|
|
|
51
55
|
def astModuleToIngredientsFunction(astModule: ast.AST, identifierFunctionDef: ast_Identifier) -> IngredientsFunction:
|
|
52
56
|
"""
|
|
@@ -97,7 +101,7 @@ def extractFunctionDef(module: ast.AST, identifier: ast_Identifier) -> ast.Funct
|
|
|
97
101
|
identifier: The name of the function to find.
|
|
98
102
|
|
|
99
103
|
Returns:
|
|
100
|
-
The matching function definition AST node, or None if not found.
|
|
104
|
+
astFunctionDef: The matching function definition AST node, or None if not found.
|
|
101
105
|
"""
|
|
102
106
|
return NodeTourist(ifThis.isFunctionDef_Identifier(identifier), Then.extractIt).captureLastMatch(module)
|
|
103
107
|
|
|
@@ -263,8 +267,8 @@ class DeReConstructField2ast:
|
|
|
263
267
|
ast_nameDOTname: ast.Attribute = dataclasses.field(init=False)
|
|
264
268
|
astAnnotation: ast.expr = dataclasses.field(init=False)
|
|
265
269
|
ast_argAnnotated: ast.arg = dataclasses.field(init=False)
|
|
266
|
-
astAnnAssignConstructor: ast.AnnAssign = dataclasses.field(init=False)
|
|
267
|
-
Z0Z_hack: tuple[ast.AnnAssign, str] = dataclasses.field(init=False)
|
|
270
|
+
astAnnAssignConstructor: ast.AnnAssign|ast.Assign = dataclasses.field(init=False)
|
|
271
|
+
Z0Z_hack: tuple[ast.AnnAssign|ast.Assign, str] = dataclasses.field(init=False)
|
|
268
272
|
|
|
269
273
|
def __post_init__(self, dataclassesDOTdataclassLogicalPathModule: str_nameDOTname, dataclassClassDef: ast.ClassDef, dataclassesDOTdataclassInstance_Identifier: ast_Identifier, field: dataclasses.Field[Any]) -> None:
|
|
270
274
|
self.compare = field.compare
|
|
@@ -287,18 +291,42 @@ class DeReConstructField2ast:
|
|
|
287
291
|
else: self.astAnnotation = sherpa
|
|
288
292
|
|
|
289
293
|
self.ast_argAnnotated = Make.arg(self.name, self.astAnnotation)
|
|
294
|
+
"""
|
|
295
|
+
from ast import Module, Expr, Subscript, Name, Tuple, Load
|
|
296
|
+
Subscript(
|
|
297
|
+
value=Name(id='ndarray', ctx=Load()),
|
|
298
|
+
slice=Tuple(
|
|
299
|
+
elts=[
|
|
300
|
+
Subscript(
|
|
301
|
+
value=Name(id='tuple', ctx=Load()),
|
|
302
|
+
slice=Name(id='int', ctx=Load()),
|
|
303
|
+
ctx=Load()),
|
|
304
|
+
Subscript(
|
|
305
|
+
value=Name(id='dtype', ctx=Load()),
|
|
306
|
+
slice=Name(id='NumPyLeavesTotal', ctx=Load()),
|
|
307
|
+
ctx=Load())],
|
|
308
|
+
ctx=Load()),
|
|
309
|
+
ctx=Load()
|
|
310
|
+
)
|
|
290
311
|
|
|
312
|
+
"""
|
|
291
313
|
dtype = self.metadata.get('dtype', None)
|
|
292
314
|
if dtype:
|
|
293
315
|
moduleWithLogicalPath: str_nameDOTname = 'numpy'
|
|
294
|
-
|
|
295
|
-
self.ledger.addImportFrom_asStr(moduleWithLogicalPath,
|
|
316
|
+
annotationType = 'ndarray'
|
|
317
|
+
self.ledger.addImportFrom_asStr(moduleWithLogicalPath, annotationType)
|
|
318
|
+
self.ledger.addImportFrom_asStr(moduleWithLogicalPath, 'dtype')
|
|
319
|
+
axesSubscript = Make.Subscript(Make.Name('tuple'), Make.Name('uint8'))
|
|
320
|
+
dtype_asnameName: ast.Name = self.astAnnotation # type: ignore
|
|
321
|
+
if dtype_asnameName.id == 'Array3D':
|
|
322
|
+
axesSubscript = Make.Subscript(Make.Name('tuple'), Make.Tuple([Make.Name('uint8'), Make.Name('uint8'), Make.Name('uint8')]))
|
|
323
|
+
ast_expr = Make.Subscript(Make.Name(annotationType), Make.Tuple([axesSubscript, Make.Subscript(Make.Name('dtype'), dtype_asnameName)]))
|
|
296
324
|
constructor = 'array'
|
|
297
325
|
self.ledger.addImportFrom_asStr(moduleWithLogicalPath, constructor)
|
|
298
326
|
dtypeIdentifier: ast_Identifier = dtype.__name__
|
|
299
|
-
dtype_asnameName: ast.Name = self.astAnnotation # type: ignore
|
|
300
327
|
self.ledger.addImportFrom_asStr(moduleWithLogicalPath, dtypeIdentifier, dtype_asnameName.id)
|
|
301
|
-
self.astAnnAssignConstructor = Make.AnnAssign(self.astName,
|
|
328
|
+
self.astAnnAssignConstructor = Make.AnnAssign(self.astName, ast_expr, Make.Call(Make.Name(constructor), list_astKeywords=[Make.keyword('dtype', dtype_asnameName)]))
|
|
329
|
+
self.astAnnAssignConstructor = Make.Assign([self.astName], Make.Call(Make.Name(constructor), list_astKeywords=[Make.keyword('dtype', dtype_asnameName)]))
|
|
302
330
|
self.Z0Z_hack = (self.astAnnAssignConstructor, 'array')
|
|
303
331
|
elif isinstance(self.astAnnotation, ast.Name):
|
|
304
332
|
self.astAnnAssignConstructor = Make.AnnAssign(self.astName, self.astAnnotation, Make.Call(self.astAnnotation, [Make.Constant(-1)]))
|
|
@@ -413,9 +441,18 @@ def write_astModule(ingredients: IngredientsModule, pathFilename: PathLike[Any]
|
|
|
413
441
|
if packageName:
|
|
414
442
|
autoflake_additional_imports.append(packageName)
|
|
415
443
|
pythonSource = autoflake_fix_code(pythonSource, autoflake_additional_imports, expand_star_imports=False, remove_all_unused_imports=True, remove_duplicate_keys = False, remove_unused_variables = False)
|
|
444
|
+
# pythonSource = python_minifier.minify(pythonSource)
|
|
416
445
|
writeStringToHere(pythonSource, pathFilename)
|
|
417
446
|
|
|
418
447
|
# END of acceptable classes and functions ======================================================
|
|
448
|
+
def removeUnusedParameters(ingredientsFunction: IngredientsFunction):
|
|
449
|
+
list_argCuzMyBrainRefusesToThink = ingredientsFunction.astFunctionDef.args.args + ingredientsFunction.astFunctionDef.args.posonlyargs + ingredientsFunction.astFunctionDef.args.kwonlyargs
|
|
450
|
+
list_arg_arg: list[ast_Identifier] = [ast_arg.arg for ast_arg in list_argCuzMyBrainRefusesToThink]
|
|
451
|
+
listName: list[ast.Name] = []
|
|
452
|
+
NodeTourist(be.Name, Then.appendTo(listName)).visit(ingredientsFunction.astFunctionDef)
|
|
453
|
+
list_Identifiers: list[ast_Identifier] = [astName.id for astName in listName]
|
|
454
|
+
list_IdentifiersNotUsed: list[ast_Identifier] = list(set(list_arg_arg) - set(list_Identifiers))
|
|
455
|
+
|
|
419
456
|
dictionaryEstimates: dict[tuple[int, ...], int] = {
|
|
420
457
|
(2,2,2,2,2,2,2,2): 798148657152000,
|
|
421
458
|
(2,21): 776374224866624,
|
|
@@ -457,3 +494,113 @@ def Z0Z_lameFindReplace(astTree: 个, mappingFindReplaceNodes: Mapping[ast.AST,
|
|
|
457
494
|
else:
|
|
458
495
|
astTree = deepcopy(newTree)
|
|
459
496
|
return newTree
|
|
497
|
+
|
|
498
|
+
def makeNewFlow(recipeFlow: RecipeSynthesizeFlow) -> IngredientsModule:
|
|
499
|
+
# TODO a tool to automatically remove unused variables from the ArgumentsSpecification (return, and returns) _might_ be nice.
|
|
500
|
+
# Figure out dynamic flow control to synthesized modules https://github.com/hunterhogan/mapFolding/issues/4
|
|
501
|
+
listAllIngredientsFunctions = [
|
|
502
|
+
(ingredientsInitialize := astModuleToIngredientsFunction(recipeFlow.source_astModule, recipeFlow.sourceCallableInitialize)),
|
|
503
|
+
(ingredientsParallel := astModuleToIngredientsFunction(recipeFlow.source_astModule, recipeFlow.sourceCallableParallel)),
|
|
504
|
+
(ingredientsSequential := astModuleToIngredientsFunction(recipeFlow.source_astModule, recipeFlow.sourceCallableSequential)),
|
|
505
|
+
(ingredientsDispatcher := astModuleToIngredientsFunction(recipeFlow.source_astModule, recipeFlow.sourceCallableDispatcher)),
|
|
506
|
+
]
|
|
507
|
+
|
|
508
|
+
# Inline functions ========================================================
|
|
509
|
+
# NOTE Replacements statements are based on the identifiers in the _source_, so operate on the source identifiers.
|
|
510
|
+
ingredientsInitialize.astFunctionDef = inlineFunctionDef(recipeFlow.sourceCallableInitialize, recipeFlow.source_astModule)
|
|
511
|
+
ingredientsParallel.astFunctionDef = inlineFunctionDef(recipeFlow.sourceCallableParallel, recipeFlow.source_astModule)
|
|
512
|
+
ingredientsSequential.astFunctionDef = inlineFunctionDef(recipeFlow.sourceCallableSequential, recipeFlow.source_astModule)
|
|
513
|
+
|
|
514
|
+
# assignRecipeIdentifiersToCallable. =============================
|
|
515
|
+
# Consolidate settings classes through inheritance https://github.com/hunterhogan/mapFolding/issues/15
|
|
516
|
+
# How can I use dataclass settings as the SSOT for specific actions? https://github.com/hunterhogan/mapFolding/issues/16
|
|
517
|
+
# NOTE reminder: you are updating these `ast.Name` here (and not in a more general search) because this is a
|
|
518
|
+
# narrow search for `ast.Call` so you won't accidentally replace unrelated `ast.Name`.
|
|
519
|
+
listFindReplace = [(recipeFlow.sourceCallableDispatcher, recipeFlow.callableDispatcher),
|
|
520
|
+
(recipeFlow.sourceCallableInitialize, recipeFlow.callableInitialize),
|
|
521
|
+
(recipeFlow.sourceCallableParallel, recipeFlow.callableParallel),
|
|
522
|
+
(recipeFlow.sourceCallableSequential, recipeFlow.callableSequential),]
|
|
523
|
+
for ingredients in listAllIngredientsFunctions:
|
|
524
|
+
for source_Identifier, recipe_Identifier in listFindReplace:
|
|
525
|
+
updateCallName = NodeChanger(ifThis.isCall_Identifier(source_Identifier), grab.funcAttribute(Then.replaceWith(Make.Name(recipe_Identifier))))
|
|
526
|
+
updateCallName.visit(ingredients.astFunctionDef)
|
|
527
|
+
|
|
528
|
+
ingredientsDispatcher.astFunctionDef.name = recipeFlow.callableDispatcher
|
|
529
|
+
ingredientsInitialize.astFunctionDef.name = recipeFlow.callableInitialize
|
|
530
|
+
ingredientsParallel.astFunctionDef.name = recipeFlow.callableParallel
|
|
531
|
+
ingredientsSequential.astFunctionDef.name = recipeFlow.callableSequential
|
|
532
|
+
|
|
533
|
+
# Assign identifiers per the recipe. ==============================
|
|
534
|
+
listFindReplace = [(recipeFlow.sourceDataclassInstance, recipeFlow.dataclassInstance),
|
|
535
|
+
(recipeFlow.sourceDataclassInstanceTaskDistribution, recipeFlow.dataclassInstanceTaskDistribution),
|
|
536
|
+
(recipeFlow.sourceConcurrencyManagerNamespace, recipeFlow.concurrencyManagerNamespace),]
|
|
537
|
+
for ingredients in listAllIngredientsFunctions:
|
|
538
|
+
for source_Identifier, recipe_Identifier in listFindReplace:
|
|
539
|
+
updateName = NodeChanger(ifThis.isName_Identifier(source_Identifier) , grab.idAttribute(Then.replaceWith(recipe_Identifier)))
|
|
540
|
+
update_arg = NodeChanger(ifThis.isArgument_Identifier(source_Identifier), grab.argAttribute(Then.replaceWith(recipe_Identifier)))
|
|
541
|
+
updateName.visit(ingredients.astFunctionDef)
|
|
542
|
+
update_arg.visit(ingredients.astFunctionDef)
|
|
543
|
+
|
|
544
|
+
updateConcurrencyManager = NodeChanger(ifThis.isCallAttributeNamespace_Identifier(recipeFlow.sourceConcurrencyManagerNamespace, recipeFlow.sourceConcurrencyManagerIdentifier)
|
|
545
|
+
, grab.funcAttribute(Then.replaceWith(Make.Attribute(Make.Name(recipeFlow.concurrencyManagerNamespace), recipeFlow.concurrencyManagerIdentifier))))
|
|
546
|
+
updateConcurrencyManager.visit(ingredientsDispatcher.astFunctionDef)
|
|
547
|
+
|
|
548
|
+
# shatter Dataclass =======================================================
|
|
549
|
+
instance_Identifier = recipeFlow.dataclassInstance
|
|
550
|
+
getTheOtherRecord_damn = recipeFlow.dataclassInstanceTaskDistribution
|
|
551
|
+
shatteredDataclass = shatter_dataclassesDOTdataclass(recipeFlow.logicalPathModuleDataclass, recipeFlow.sourceDataclassIdentifier, instance_Identifier)
|
|
552
|
+
ingredientsDispatcher.imports.update(shatteredDataclass.ledger)
|
|
553
|
+
|
|
554
|
+
# How can I use dataclass settings as the SSOT for specific actions? https://github.com/hunterhogan/mapFolding/issues/16
|
|
555
|
+
# Change callable parameters and Call to the callable at the same time ====
|
|
556
|
+
# sequentialCallable =========================================================
|
|
557
|
+
if recipeFlow.removeDataclassSequential:
|
|
558
|
+
ingredientsSequential.astFunctionDef.args = Make.argumentsSpecification(args=shatteredDataclass.list_argAnnotated4ArgumentsSpecification)
|
|
559
|
+
astCallSequentialCallable = Make.Call(Make.Name(recipeFlow.callableSequential), shatteredDataclass.listName4Parameters)
|
|
560
|
+
changeReturnSequentialCallable = NodeChanger(be.Return, Then.replaceWith(Make.Return(shatteredDataclass.fragments4AssignmentOrParameters)))
|
|
561
|
+
ingredientsSequential.astFunctionDef.returns = shatteredDataclass.signatureReturnAnnotation
|
|
562
|
+
replaceAssignSequentialCallable = NodeChanger(ifThis.isAssignAndValueIs(ifThis.isCall_Identifier(recipeFlow.callableSequential)), Then.replaceWith(Make.Assign(listTargets=[shatteredDataclass.fragments4AssignmentOrParameters], value=astCallSequentialCallable)))
|
|
563
|
+
|
|
564
|
+
unpack4sequentialCallable = NodeChanger(ifThis.isAssignAndValueIs(ifThis.isCall_Identifier(recipeFlow.callableSequential)), Then.insertThisAbove(shatteredDataclass.listUnpack))
|
|
565
|
+
repack4sequentialCallable = NodeChanger(ifThis.isAssignAndValueIs(ifThis.isCall_Identifier(recipeFlow.callableSequential)), Then.insertThisBelow([shatteredDataclass.repack]))
|
|
566
|
+
|
|
567
|
+
changeReturnSequentialCallable.visit(ingredientsSequential.astFunctionDef)
|
|
568
|
+
replaceAssignSequentialCallable.visit(ingredientsDispatcher.astFunctionDef)
|
|
569
|
+
unpack4sequentialCallable.visit(ingredientsDispatcher.astFunctionDef)
|
|
570
|
+
repack4sequentialCallable.visit(ingredientsDispatcher.astFunctionDef)
|
|
571
|
+
|
|
572
|
+
ingredientsSequential.astFunctionDef = Z0Z_lameFindReplace(ingredientsSequential.astFunctionDef, shatteredDataclass.map_stateDOTfield2Name)
|
|
573
|
+
|
|
574
|
+
# parallelCallable =========================================================
|
|
575
|
+
if recipeFlow.removeDataclassParallel:
|
|
576
|
+
ingredientsParallel.astFunctionDef.args = Make.argumentsSpecification(args=shatteredDataclass.list_argAnnotated4ArgumentsSpecification)
|
|
577
|
+
replaceCall2concurrencyManager = NodeChanger(ifThis.isCallAttributeNamespace_Identifier(recipeFlow.concurrencyManagerNamespace, recipeFlow.concurrencyManagerIdentifier), Then.replaceWith(Make.Call(Make.Attribute(Make.Name(recipeFlow.concurrencyManagerNamespace), recipeFlow.concurrencyManagerIdentifier), listArguments=[Make.Name(recipeFlow.callableParallel)] + shatteredDataclass.listName4Parameters)))
|
|
578
|
+
|
|
579
|
+
# NOTE I am dissatisfied with this logic for many reasons, including that it requires separate NodeCollector and NodeReplacer instances.
|
|
580
|
+
astCallConcurrencyResult: list[ast.Call] = []
|
|
581
|
+
get_astCallConcurrencyResult = NodeTourist(ifThis.isAssignAndTargets0Is(ifThis.isSubscript_Identifier(getTheOtherRecord_damn)), getIt(astCallConcurrencyResult))
|
|
582
|
+
get_astCallConcurrencyResult.visit(ingredientsDispatcher.astFunctionDef)
|
|
583
|
+
replaceAssignParallelCallable = NodeChanger(ifThis.isAssignAndTargets0Is(ifThis.isSubscript_Identifier(getTheOtherRecord_damn)), grab.valueAttribute(Then.replaceWith(astCallConcurrencyResult[0])))
|
|
584
|
+
replaceAssignParallelCallable.visit(ingredientsDispatcher.astFunctionDef)
|
|
585
|
+
changeReturnParallelCallable = NodeChanger(be.Return, Then.replaceWith(Make.Return(shatteredDataclass.countingVariableName)))
|
|
586
|
+
ingredientsParallel.astFunctionDef.returns = shatteredDataclass.countingVariableAnnotation
|
|
587
|
+
|
|
588
|
+
unpack4parallelCallable = NodeChanger(ifThis.isAssignAndValueIs(ifThis.isCallAttributeNamespace_Identifier(recipeFlow.concurrencyManagerNamespace, recipeFlow.concurrencyManagerIdentifier)), Then.insertThisAbove(shatteredDataclass.listUnpack))
|
|
589
|
+
|
|
590
|
+
unpack4parallelCallable.visit(ingredientsDispatcher.astFunctionDef)
|
|
591
|
+
replaceCall2concurrencyManager.visit(ingredientsDispatcher.astFunctionDef)
|
|
592
|
+
changeReturnParallelCallable.visit(ingredientsParallel.astFunctionDef)
|
|
593
|
+
|
|
594
|
+
ingredientsParallel.astFunctionDef = Z0Z_lameFindReplace(ingredientsParallel.astFunctionDef, shatteredDataclass.map_stateDOTfield2Name)
|
|
595
|
+
|
|
596
|
+
# Module-level transformations ===========================================================
|
|
597
|
+
ingredientsModuleNumbaUnified = IngredientsModule(ingredientsFunction=listAllIngredientsFunctions, imports=LedgerOfImports(recipeFlow.source_astModule))
|
|
598
|
+
ingredientsModuleNumbaUnified.removeImportFromModule('numpy')
|
|
599
|
+
|
|
600
|
+
return ingredientsModuleNumbaUnified
|
|
601
|
+
|
|
602
|
+
def getIt(astCallConcurrencyResult: list[ast.Call]) -> Callable[[ast.AST], ast.AST]:
|
|
603
|
+
def workhorse(node: ast.AST) -> ast.AST:
|
|
604
|
+
NodeTourist(be.Call, Then.appendTo(astCallConcurrencyResult)).visit(node)
|
|
605
|
+
return node
|
|
606
|
+
return workhorse
|
|
@@ -47,7 +47,7 @@ def countInitialize(state: ComputationState) -> ComputationState:
|
|
|
47
47
|
return state
|
|
48
48
|
|
|
49
49
|
@jit(_nrt=True, boundscheck=False, cache=True, error_model='numpy', fastmath=True, forceinline=True, inline='always', looplift=False, no_cfunc_wrapper=False, no_cpython_wrapper=False, nopython=True, parallel=False)
|
|
50
|
-
def countParallel(mapShape: tuple[DatatypeLeavesTotal, ...], leavesTotal: DatatypeLeavesTotal, taskDivisions: DatatypeLeavesTotal, concurrencyLimit: DatatypeElephino, connectionGraph: Array3D, dimensionsTotal: DatatypeLeavesTotal, countDimensionsGapped: Array1DLeavesTotal, dimensionsUnconstrained: DatatypeLeavesTotal, gapRangeStart: Array1DElephino, gapsWhere: Array1DLeavesTotal, leafAbove: Array1DLeavesTotal, leafBelow: Array1DLeavesTotal, foldGroups: Array1DFoldsTotal, foldsTotal: DatatypeFoldsTotal, gap1ndex: DatatypeLeavesTotal, gap1ndexCeiling: DatatypeElephino, groupsOfFolds: DatatypeFoldsTotal, indexDimension: DatatypeLeavesTotal, indexLeaf: DatatypeLeavesTotal, indexMiniGap: DatatypeElephino, leaf1ndex:
|
|
50
|
+
def countParallel(mapShape: tuple[DatatypeLeavesTotal, ...], leavesTotal: DatatypeLeavesTotal, taskDivisions: DatatypeLeavesTotal, concurrencyLimit: DatatypeElephino, connectionGraph: Array3D, dimensionsTotal: DatatypeLeavesTotal, countDimensionsGapped: Array1DLeavesTotal, dimensionsUnconstrained: DatatypeLeavesTotal, gapRangeStart: Array1DElephino, gapsWhere: Array1DLeavesTotal, leafAbove: Array1DLeavesTotal, leafBelow: Array1DLeavesTotal, foldGroups: Array1DFoldsTotal, foldsTotal: DatatypeFoldsTotal, gap1ndex: DatatypeLeavesTotal, gap1ndexCeiling: DatatypeElephino, groupsOfFolds: DatatypeFoldsTotal, indexDimension: DatatypeLeavesTotal, indexLeaf: DatatypeLeavesTotal, indexMiniGap: DatatypeElephino, leaf1ndex: DatatypeLeavesTotal, leafConnectee: DatatypeElephino, taskIndex: DatatypeLeavesTotal) -> DatatypeFoldsTotal:
|
|
51
51
|
while leaf1ndex > 0:
|
|
52
52
|
if leaf1ndex <= 1 or leafBelow[0] == 1:
|
|
53
53
|
if leaf1ndex > leavesTotal:
|
|
@@ -92,7 +92,7 @@ def countParallel(mapShape: tuple[DatatypeLeavesTotal, ...], leavesTotal: Dataty
|
|
|
92
92
|
return groupsOfFolds
|
|
93
93
|
|
|
94
94
|
@jit(_nrt=True, boundscheck=False, cache=True, error_model='numpy', fastmath=True, forceinline=True, inline='always', looplift=False, no_cfunc_wrapper=False, no_cpython_wrapper=False, nopython=True, parallel=False)
|
|
95
|
-
def countSequential(mapShape: tuple[DatatypeLeavesTotal, ...], leavesTotal: DatatypeLeavesTotal, taskDivisions: DatatypeLeavesTotal, concurrencyLimit: DatatypeElephino, connectionGraph: Array3D, dimensionsTotal: DatatypeLeavesTotal, countDimensionsGapped: Array1DLeavesTotal, dimensionsUnconstrained: DatatypeLeavesTotal, gapRangeStart: Array1DElephino, gapsWhere: Array1DLeavesTotal, leafAbove: Array1DLeavesTotal, leafBelow: Array1DLeavesTotal, foldGroups: Array1DFoldsTotal, foldsTotal: DatatypeFoldsTotal, gap1ndex: DatatypeLeavesTotal, gap1ndexCeiling: DatatypeElephino, groupsOfFolds: DatatypeFoldsTotal, indexDimension: DatatypeLeavesTotal, indexLeaf: DatatypeLeavesTotal, indexMiniGap: DatatypeElephino, leaf1ndex:
|
|
95
|
+
def countSequential(mapShape: tuple[DatatypeLeavesTotal, ...], leavesTotal: DatatypeLeavesTotal, taskDivisions: DatatypeLeavesTotal, concurrencyLimit: DatatypeElephino, connectionGraph: Array3D, dimensionsTotal: DatatypeLeavesTotal, countDimensionsGapped: Array1DLeavesTotal, dimensionsUnconstrained: DatatypeLeavesTotal, gapRangeStart: Array1DElephino, gapsWhere: Array1DLeavesTotal, leafAbove: Array1DLeavesTotal, leafBelow: Array1DLeavesTotal, foldGroups: Array1DFoldsTotal, foldsTotal: DatatypeFoldsTotal, gap1ndex: DatatypeLeavesTotal, gap1ndexCeiling: DatatypeElephino, groupsOfFolds: DatatypeFoldsTotal, indexDimension: DatatypeLeavesTotal, indexLeaf: DatatypeLeavesTotal, indexMiniGap: DatatypeElephino, leaf1ndex: DatatypeLeavesTotal, leafConnectee: DatatypeElephino, taskIndex: DatatypeLeavesTotal) -> tuple[tuple[DatatypeLeavesTotal, ...], DatatypeLeavesTotal, DatatypeLeavesTotal, DatatypeElephino, Array3D, DatatypeLeavesTotal, Array1DLeavesTotal, DatatypeLeavesTotal, Array1DElephino, Array1DLeavesTotal, Array1DLeavesTotal, Array1DLeavesTotal, Array1DFoldsTotal, DatatypeFoldsTotal, DatatypeLeavesTotal, DatatypeElephino, DatatypeFoldsTotal, DatatypeLeavesTotal, DatatypeLeavesTotal, DatatypeElephino, DatatypeLeavesTotal, DatatypeElephino, DatatypeLeavesTotal]:
|
|
96
96
|
while leaf1ndex > 0:
|
|
97
97
|
if leaf1ndex <= 1 or leafBelow[0] == 1:
|
|
98
98
|
if leaf1ndex > leavesTotal:
|
|
@@ -124,6 +124,9 @@ def countSequential(mapShape: tuple[DatatypeLeavesTotal, ...], leavesTotal: Data
|
|
|
124
124
|
leaf1ndex -= 1
|
|
125
125
|
leafBelow[leafAbove[leaf1ndex]] = leafBelow[leaf1ndex]
|
|
126
126
|
leafAbove[leafBelow[leaf1ndex]] = leafAbove[leaf1ndex]
|
|
127
|
+
if groupsOfFolds and leaf1ndex == 3:
|
|
128
|
+
groupsOfFolds *= 2
|
|
129
|
+
break
|
|
127
130
|
if leaf1ndex > 0:
|
|
128
131
|
gap1ndex -= 1
|
|
129
132
|
leafAbove[leaf1ndex] = gapsWhere[gap1ndex]
|
|
@@ -164,7 +167,7 @@ def doTheNeedful(state: ComputationState) -> ComputationState:
|
|
|
164
167
|
indexDimension: DatatypeLeavesTotal = state.indexDimension
|
|
165
168
|
indexLeaf: DatatypeLeavesTotal = state.indexLeaf
|
|
166
169
|
indexMiniGap: DatatypeElephino = state.indexMiniGap
|
|
167
|
-
leaf1ndex:
|
|
170
|
+
leaf1ndex: DatatypeLeavesTotal = state.leaf1ndex
|
|
168
171
|
leafConnectee: DatatypeElephino = state.leafConnectee
|
|
169
172
|
taskIndex: DatatypeLeavesTotal = state.taskIndex
|
|
170
173
|
dictionaryConcurrency[indexSherpa] = concurrencyManager.submit(countParallel, mapShape, leavesTotal, taskDivisions, concurrencyLimit, connectionGraph, dimensionsTotal, countDimensionsGapped, dimensionsUnconstrained, gapRangeStart, gapsWhere, leafAbove, leafBelow, foldGroups, foldsTotal, gap1ndex, gap1ndexCeiling, groupsOfFolds, indexDimension, indexLeaf, indexMiniGap, leaf1ndex, leafConnectee, taskIndex)
|
|
@@ -192,7 +195,7 @@ def doTheNeedful(state: ComputationState) -> ComputationState:
|
|
|
192
195
|
indexDimension: DatatypeLeavesTotal = state.indexDimension
|
|
193
196
|
indexLeaf: DatatypeLeavesTotal = state.indexLeaf
|
|
194
197
|
indexMiniGap: DatatypeElephino = state.indexMiniGap
|
|
195
|
-
leaf1ndex:
|
|
198
|
+
leaf1ndex: DatatypeLeavesTotal = state.leaf1ndex
|
|
196
199
|
leafConnectee: DatatypeElephino = state.leafConnectee
|
|
197
200
|
taskIndex: DatatypeLeavesTotal = state.taskIndex
|
|
198
201
|
mapShape, leavesTotal, taskDivisions, concurrencyLimit, connectionGraph, dimensionsTotal, countDimensionsGapped, dimensionsUnconstrained, gapRangeStart, gapsWhere, leafAbove, leafBelow, foldGroups, foldsTotal, gap1ndex, gap1ndexCeiling, groupsOfFolds, indexDimension, indexLeaf, indexMiniGap, leaf1ndex, leafConnectee, taskIndex = countSequential(mapShape, leavesTotal, taskDivisions, concurrencyLimit, connectionGraph, dimensionsTotal, countDimensionsGapped, dimensionsUnconstrained, gapRangeStart, gapsWhere, leafAbove, leafBelow, foldGroups, foldsTotal, gap1ndex, gap1ndexCeiling, groupsOfFolds, indexDimension, indexLeaf, indexMiniGap, leaf1ndex, leafConnectee, taskIndex)
|
mapFolding/theDao.py
CHANGED
|
@@ -43,12 +43,6 @@ def activeLeafIsTheFirstLeaf(state: ComputationState) -> bool:
|
|
|
43
43
|
def allDimensionsAreUnconstrained(state: ComputationState) -> bool:
|
|
44
44
|
return not state.dimensionsUnconstrained
|
|
45
45
|
|
|
46
|
-
def undoLastLeafPlacement(state: ComputationState) -> ComputationState:
|
|
47
|
-
state.leaf1ndex -= 1
|
|
48
|
-
state.leafBelow[state.leafAbove[state.leaf1ndex]] = state.leafBelow[state.leaf1ndex]
|
|
49
|
-
state.leafAbove[state.leafBelow[state.leaf1ndex]] = state.leafAbove[state.leaf1ndex]
|
|
50
|
-
return state
|
|
51
|
-
|
|
52
46
|
def countGaps(state: ComputationState) -> ComputationState:
|
|
53
47
|
state.gapsWhere[state.gap1ndexCeiling] = state.leafConnectee
|
|
54
48
|
if state.countDimensionsGapped[state.leafConnectee] == 0:
|
|
@@ -100,6 +94,16 @@ def initializeVariablesToFindGaps(state: ComputationState) -> ComputationState:
|
|
|
100
94
|
state.indexDimension = 0
|
|
101
95
|
return state
|
|
102
96
|
|
|
97
|
+
def insertLeafAtGap(state: ComputationState) -> ComputationState:
|
|
98
|
+
state.gap1ndex -= 1
|
|
99
|
+
state.leafAbove[state.leaf1ndex] = state.gapsWhere[state.gap1ndex]
|
|
100
|
+
state.leafBelow[state.leaf1ndex] = state.leafBelow[state.leafAbove[state.leaf1ndex]]
|
|
101
|
+
state.leafBelow[state.leafAbove[state.leaf1ndex]] = state.leaf1ndex
|
|
102
|
+
state.leafAbove[state.leafBelow[state.leaf1ndex]] = state.leaf1ndex
|
|
103
|
+
state.gapRangeStart[state.leaf1ndex] = state.gap1ndex
|
|
104
|
+
state.leaf1ndex += 1
|
|
105
|
+
return state
|
|
106
|
+
|
|
103
107
|
def insertUnconstrainedLeaf(state: ComputationState) -> ComputationState:
|
|
104
108
|
state.indexLeaf = 0
|
|
105
109
|
while state.indexLeaf < state.leaf1ndex:
|
|
@@ -123,22 +127,18 @@ def loopUpToDimensionsTotal(state: ComputationState) -> bool:
|
|
|
123
127
|
def noGapsHere(state: ComputationState) -> bool:
|
|
124
128
|
return (state.leaf1ndex > 0) and (state.gap1ndex == state.gapRangeStart[state.leaf1ndex - 1])
|
|
125
129
|
|
|
126
|
-
def insertLeafAtGap(state: ComputationState) -> ComputationState:
|
|
127
|
-
state.gap1ndex -= 1
|
|
128
|
-
state.leafAbove[state.leaf1ndex] = state.gapsWhere[state.gap1ndex]
|
|
129
|
-
state.leafBelow[state.leaf1ndex] = state.leafBelow[state.leafAbove[state.leaf1ndex]]
|
|
130
|
-
state.leafBelow[state.leafAbove[state.leaf1ndex]] = state.leaf1ndex
|
|
131
|
-
state.leafAbove[state.leafBelow[state.leaf1ndex]] = state.leaf1ndex
|
|
132
|
-
state.gapRangeStart[state.leaf1ndex] = state.gap1ndex
|
|
133
|
-
state.leaf1ndex += 1
|
|
134
|
-
return state
|
|
135
|
-
|
|
136
130
|
def thereIsAnActiveLeaf(state: ComputationState) -> bool:
|
|
137
131
|
return state.leaf1ndex > 0
|
|
138
132
|
|
|
139
133
|
def thisIsMyTaskIndex(state: ComputationState) -> bool:
|
|
140
134
|
return (state.leaf1ndex != state.taskDivisions) or (state.leafConnectee % state.taskDivisions == state.taskIndex)
|
|
141
135
|
|
|
136
|
+
def undoLastLeafPlacement(state: ComputationState) -> ComputationState:
|
|
137
|
+
state.leaf1ndex -= 1
|
|
138
|
+
state.leafBelow[state.leafAbove[state.leaf1ndex]] = state.leafBelow[state.leaf1ndex]
|
|
139
|
+
state.leafAbove[state.leafBelow[state.leaf1ndex]] = state.leafAbove[state.leaf1ndex]
|
|
140
|
+
return state
|
|
141
|
+
|
|
142
142
|
def updateLeafConnectee(state: ComputationState) -> ComputationState:
|
|
143
143
|
state.leafConnectee = state.connectionGraph[state.indexDimension, state.leaf1ndex, state.leafBelow[state.leafConnectee]]
|
|
144
144
|
return state
|
|
@@ -218,6 +218,9 @@ def countSequential(state: ComputationState) -> ComputationState:
|
|
|
218
218
|
state = incrementIndexMiniGap(state)
|
|
219
219
|
while noGapsHere(state):
|
|
220
220
|
state = undoLastLeafPlacement(state)
|
|
221
|
+
if state.groupsOfFolds and state.leaf1ndex == 3:
|
|
222
|
+
state.groupsOfFolds *= 2
|
|
223
|
+
break
|
|
221
224
|
if thereIsAnActiveLeaf(state):
|
|
222
225
|
state = insertLeafAtGap(state)
|
|
223
226
|
state.foldGroups[state.taskIndex] = state.groupsOfFolds
|