mapFolding 0.4.3__py3-none-any.whl → 0.5.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.
Files changed (41) hide show
  1. mapFolding/__init__.py +93 -58
  2. mapFolding/basecamp.py +9 -11
  3. mapFolding/beDRY.py +24 -23
  4. mapFolding/oeis.py +47 -45
  5. mapFolding/theDao.py +48 -48
  6. mapFolding/theSSOT.py +22 -20
  7. mapFolding/theSSOTdatatypes.py +20 -32
  8. {mapFolding-0.4.3.dist-info → mapFolding-0.5.1.dist-info}/METADATA +3 -1
  9. mapFolding-0.5.1.dist-info/RECORD +14 -0
  10. {mapFolding-0.4.3.dist-info → mapFolding-0.5.1.dist-info}/top_level.txt +0 -1
  11. mapFolding/reference/flattened.py +0 -377
  12. mapFolding/reference/hunterNumba.py +0 -132
  13. mapFolding/reference/irvineJavaPort.py +0 -120
  14. mapFolding/reference/jax.py +0 -208
  15. mapFolding/reference/lunnan.py +0 -153
  16. mapFolding/reference/lunnanNumpy.py +0 -123
  17. mapFolding/reference/lunnanWhile.py +0 -121
  18. mapFolding/reference/rotatedEntryPoint.py +0 -240
  19. mapFolding/reference/total_countPlus1vsPlusN.py +0 -211
  20. mapFolding/someAssemblyRequired/__init__.py +0 -5
  21. mapFolding/someAssemblyRequired/getLLVMforNoReason.py +0 -19
  22. mapFolding/someAssemblyRequired/makeJob.py +0 -55
  23. mapFolding/someAssemblyRequired/synthesizeModuleJAX.py +0 -29
  24. mapFolding/someAssemblyRequired/synthesizeNumba.py +0 -340
  25. mapFolding/someAssemblyRequired/synthesizeNumbaGeneralized.py +0 -396
  26. mapFolding/someAssemblyRequired/synthesizeNumbaJob.py +0 -162
  27. mapFolding/someAssemblyRequired/synthesizeNumbaModules.py +0 -129
  28. mapFolding/syntheticModules/numbaCount.py +0 -158
  29. mapFolding/syntheticModules/numba_doTheNeedful.py +0 -13
  30. mapFolding-0.4.3.dist-info/RECORD +0 -40
  31. tests/__init__.py +0 -1
  32. tests/conftest.py +0 -306
  33. tests/test_computations.py +0 -43
  34. tests/test_oeis.py +0 -129
  35. tests/test_other.py +0 -171
  36. tests/test_tasks.py +0 -40
  37. tests/test_types.py +0 -5
  38. /mapFolding/{syntheticModules/__init__.py → py.typed} +0 -0
  39. {mapFolding-0.4.3.dist-info → mapFolding-0.5.1.dist-info}/LICENSE +0 -0
  40. {mapFolding-0.4.3.dist-info → mapFolding-0.5.1.dist-info}/WHEEL +0 -0
  41. {mapFolding-0.4.3.dist-info → mapFolding-0.5.1.dist-info}/entry_points.txt +0 -0
@@ -1,340 +0,0 @@
1
- """I think this module is free of hardcoded values.
2
- TODO: consolidate the logic in this module."""
3
- from mapFolding.someAssemblyRequired.synthesizeNumbaGeneralized import *
4
-
5
- def insertArrayIn_body(FunctionDefTarget: ast.FunctionDef, identifier: str, arrayTarget: numpy.ndarray, allImports: UniversalImportTracker, unrollSlices: Optional[int]=None) -> Tuple[ast.FunctionDef, UniversalImportTracker]:
6
- arrayType = type(arrayTarget)
7
- moduleConstructor = arrayType.__module__
8
- constructorName = arrayType.__name__
9
- # NOTE hack
10
- constructorName = constructorName.replace('ndarray', 'array')
11
- argData_dtype: numpy.dtype = arrayTarget.dtype
12
- datatypeName = argData_dtype.name
13
- dtypeAsName = f"{moduleConstructor}_{datatypeName}"
14
-
15
- allImports.addImportFromStr(moduleConstructor, constructorName)
16
- allImports.addImportFromStr(moduleConstructor, datatypeName, dtypeAsName)
17
-
18
- def insertAssign(assignee: str, arraySlice: numpy.ndarray) -> None:
19
- nonlocal FunctionDefTarget
20
- onlyDataRLE = autoDecodingRLE(arraySlice, addSpaces=True)
21
- astStatement = cast(ast.Expr, ast.parse(onlyDataRLE).body[0])
22
- dataAst = astStatement.value
23
-
24
- arrayCall = Then.make_astCall(name=constructorName, args=[dataAst], list_astKeywords=[ast.keyword(arg='dtype', value=ast.Name(id=dtypeAsName, ctx=ast.Load()))])
25
-
26
- assignment = ast.Assign(targets=[ast.Name(id=assignee, ctx=ast.Store())], value=arrayCall)#NOTE
27
- FunctionDefTarget.body.insert(0, assignment)
28
-
29
- if not unrollSlices:
30
- insertAssign(identifier, arrayTarget)
31
- else:
32
- for index, arraySlice in enumerate(arrayTarget):
33
- insertAssign(f"{identifier}_{index}", arraySlice)
34
-
35
- return FunctionDefTarget, allImports
36
-
37
- def findAndReplaceTrackArrayIn_body(FunctionDefTarget: ast.FunctionDef, identifier: str , arrayTarget: numpy.ndarray , allImports: UniversalImportTracker) -> Tuple[ast.FunctionDef, UniversalImportTracker]:
38
-
39
- arrayType = type(arrayTarget)
40
- moduleConstructor = arrayType.__module__
41
- constructorName = arrayType.__name__
42
- # NOTE hack
43
- constructorName = constructorName.replace('ndarray', 'array')
44
- allImports.addImportFromStr(moduleConstructor, constructorName)
45
-
46
- for statement in FunctionDefTarget.body.copy():
47
- if ifThis.isUnpackingAnArray(identifier)(statement):
48
- datatypeName = hackSSOTdatatype(statement.targets[0].id) # type: ignore
49
- dtypeAsName = f"{moduleConstructor}_{datatypeName}"
50
- indexAsStr = ast.unparse(statement.value.slice) # type: ignore
51
- arraySlice = arrayTarget[eval(indexAsStr)]
52
-
53
- onlyDataRLE = autoDecodingRLE(arraySlice, addSpaces=True)
54
- astStatement = cast(ast.Expr, ast.parse(onlyDataRLE).body[0])
55
- dataAst = astStatement.value
56
-
57
- arrayCall = Then.make_astCall(name=constructorName, args=[dataAst], list_astKeywords=[ast.keyword(arg='dtype', value=ast.Name(id=dtypeAsName, ctx=ast.Load()))])
58
-
59
- assignment = ast.Assign(targets=[statement.targets[0]], value=arrayCall) # type: ignore
60
- FunctionDefTarget.body.insert(0, assignment)
61
- FunctionDefTarget.body.remove(statement)
62
- allImports.addImportFromStr(moduleConstructor, datatypeName, dtypeAsName)
63
- return FunctionDefTarget, allImports
64
-
65
- def findAndReplaceArraySubscriptIn_body(FunctionDefTarget: ast.FunctionDef, identifier: str, arrayTarget: numpy.ndarray, Z0Z_listChaff: List[str], allImports: UniversalImportTracker) -> Tuple[ast.FunctionDef, UniversalImportTracker]:
66
- moduleConstructor = Z0Z_getDatatypeModuleScalar()
67
- for statement in FunctionDefTarget.body.copy():
68
- if ifThis.isUnpackingAnArray(identifier)(statement):
69
- astSubscript: ast.Subscript = statement.value # type: ignore
70
- astAssignee: ast.Name = statement.targets[0] # type: ignore
71
- argData_dtypeName = hackSSOTdatatype(astAssignee.id)
72
- allImports.addImportFromStr(moduleConstructor, argData_dtypeName)
73
- indexAs_astAttribute: ast.Attribute = astSubscript.slice # type: ignore
74
- indexAsStr = ast.unparse(indexAs_astAttribute)
75
- argDataSlice: int = arrayTarget[eval(indexAsStr)].item()
76
- astCall = ast.Call(func=ast.Name(id=argData_dtypeName, ctx=ast.Load()), args=[ast.Constant(value=argDataSlice)], keywords=[])
77
- assignment = ast.Assign(targets=[astAssignee], value=astCall)
78
- if astAssignee.id not in Z0Z_listChaff:
79
- FunctionDefTarget.body.insert(0, assignment)
80
- FunctionDefTarget.body.remove(statement)
81
- return FunctionDefTarget, allImports
82
-
83
- def removeAssignTargetFrom_body(FunctionDefTarget: ast.FunctionDef, identifier: str) -> ast.FunctionDef:
84
- # Remove assignment nodes where the target is either a Subscript referencing `identifier` or satisfies ifThis.nameIs(identifier).
85
- def predicate(astNode: ast.AST) -> bool:
86
- if not isinstance(astNode, ast.Assign) or not astNode.targets:
87
- return False
88
- targetNode = astNode.targets[0]
89
- return (isinstance(targetNode, ast.Subscript) and isinstance(targetNode.value, ast.Name) and targetNode.value.id == identifier) or ifThis.nameIs(identifier)(targetNode)
90
- def replacementBuilder(astNode: ast.AST) -> Optional[ast.stmt]:
91
- # Returning None removes the node.
92
- return None
93
- FunctionDefSherpa = NodeReplacer(predicate, replacementBuilder).visit(FunctionDefTarget)
94
- if not FunctionDefSherpa:
95
- raise FREAKOUT("Dude, where's my function?")
96
- else:
97
- FunctionDefTarget = cast(ast.FunctionDef, FunctionDefSherpa)
98
- ast.fix_missing_locations(FunctionDefTarget)
99
- return FunctionDefTarget
100
-
101
- def findAndReplaceAnnAssignIn_body(FunctionDefTarget: ast.FunctionDef, allImports: UniversalImportTracker) -> Tuple[ast.FunctionDef, UniversalImportTracker]:
102
- moduleConstructor = Z0Z_getDatatypeModuleScalar()
103
- for stmt in FunctionDefTarget.body.copy():
104
- if isinstance(stmt, ast.AnnAssign):
105
- if isinstance(stmt.target, ast.Name) and isinstance(stmt.value, ast.Constant):
106
- astAssignee: ast.Name = stmt.target
107
- argData_dtypeName = hackSSOTdatatype(astAssignee.id)
108
- allImports.addImportFromStr(moduleConstructor, argData_dtypeName)
109
- astCall = ast.Call(func=ast.Name(id=argData_dtypeName, ctx=ast.Load()) , args=[stmt.value], keywords=[])
110
- assignment = ast.Assign(targets=[astAssignee], value=astCall)
111
- FunctionDefTarget.body.insert(0, assignment)
112
- FunctionDefTarget.body.remove(stmt)
113
- return FunctionDefTarget, allImports
114
-
115
- def findThingyReplaceWithConstantIn_body(FunctionDefTarget: ast.FunctionDef, object: str, value: int) -> ast.FunctionDef:
116
- """
117
- Replaces nodes in astFunction matching the AST of the string `object`
118
- with a constant node holding the provided value.
119
- """
120
- targetExpression = ast.parse(object, mode='eval').body
121
- targetDump = ast.dump(targetExpression, annotate_fields=False)
122
-
123
- def findNode(node: ast.AST) -> bool:
124
- return ast.dump(node, annotate_fields=False) == targetDump
125
-
126
- def replaceWithConstant(node: ast.AST) -> ast.AST:
127
- return ast.copy_location(ast.Constant(value=value), node)
128
-
129
- transformer = NodeReplacer(findNode, replaceWithConstant)
130
- newFunction = cast(ast.FunctionDef, transformer.visit(FunctionDefTarget))
131
- ast.fix_missing_locations(newFunction)
132
- return newFunction
133
-
134
- def findAstNameReplaceWithConstantIn_body(FunctionDefTarget: ast.FunctionDef, name: str, value: int) -> ast.FunctionDef:
135
- def replaceWithConstant(node: ast.AST) -> ast.AST:
136
- return ast.copy_location(ast.Constant(value=value), node)
137
-
138
- return cast(ast.FunctionDef, NodeReplacer(ifThis.nameIs(name), replaceWithConstant).visit(FunctionDefTarget))
139
-
140
- def insertReturnStatementIn_body(FunctionDefTarget: ast.FunctionDef, arrayTarget: numpy.ndarray, allImports: UniversalImportTracker) -> Tuple[ast.FunctionDef, UniversalImportTracker]:
141
- """Add multiplication and return statement to function, properly constructing AST nodes."""
142
- # Create AST for multiplication operation
143
- multiplicand = Z0Z_identifierCountFolds
144
- datatype = hackSSOTdatatype(multiplicand)
145
- multiplyOperation = ast.BinOp(
146
- left=ast.Name(id=multiplicand, ctx=ast.Load()),
147
- op=ast.Mult(), right=ast.Constant(value=int(arrayTarget[-1])))
148
-
149
- returnStatement = ast.Return(value=multiplyOperation)
150
-
151
- datatype = hackSSOTdatatype(Z0Z_identifierCountFolds)
152
- FunctionDefTarget.returns = ast.Name(id=datatype, ctx=ast.Load())
153
- datatypeModuleScalar = Z0Z_getDatatypeModuleScalar()
154
- allImports.addImportFromStr(datatypeModuleScalar, datatype)
155
-
156
- FunctionDefTarget.body.append(returnStatement)
157
-
158
- return FunctionDefTarget, allImports
159
-
160
- def findAndReplaceWhileLoopIn_body(FunctionDefTarget: ast.FunctionDef, iteratorName: str, iterationsTotal: int) -> Any:
161
- """
162
- Unroll all nested while loops matching the condition that their test uses `iteratorName`.
163
- """
164
- # Helper transformer to replace iterator occurrences with a constant.
165
- class ReplaceIterator(ast.NodeTransformer):
166
- def __init__(self, iteratorName: str, constantValue: int) -> None:
167
- super().__init__()
168
- self.iteratorName = iteratorName
169
- self.constantValue = constantValue
170
-
171
- def visit_Name(self, node: ast.Name) -> ast.AST:
172
- if node.id == self.iteratorName:
173
- return ast.copy_location(ast.Constant(value=self.constantValue), node)
174
- return self.generic_visit(node)
175
-
176
- # NodeTransformer that finds while loops (even if deeply nested) and unrolls them.
177
- class WhileLoopUnroller(ast.NodeTransformer):
178
- def __init__(self, iteratorName: str, iterationsTotal: int) -> None:
179
- super().__init__()
180
- self.iteratorName = iteratorName
181
- self.iterationsTotal = iterationsTotal
182
-
183
- def visit_While(self, node: ast.While) -> List[ast.stmt]:
184
- # Check if the while loop's test uses the iterator.
185
- if isinstance(node.test, ast.Compare) and ifThis.nameIs(self.iteratorName)(node.test.left):
186
- # Recurse the while loop body and remove AugAssign that increments the iterator.
187
- cleanBodyStatements: List[ast.stmt] = []
188
- for loopStatement in node.body:
189
- # Recursively visit nested statements.
190
- visitedStatement = self.visit(loopStatement)
191
- # Remove direct AugAssign: iterator += 1.
192
- if (isinstance(loopStatement, ast.AugAssign) and
193
- isinstance(loopStatement.target, ast.Name) and
194
- loopStatement.target.id == self.iteratorName and
195
- isinstance(loopStatement.op, ast.Add) and
196
- isinstance(loopStatement.value, ast.Constant) and
197
- loopStatement.value.value == 1):
198
- continue
199
- cleanBodyStatements.append(visitedStatement)
200
-
201
- newStatements: List[ast.stmt] = []
202
- # Unroll using the filtered body.
203
- for iterationIndex in range(self.iterationsTotal):
204
- for loopStatement in cleanBodyStatements:
205
- copiedStatement = copy.deepcopy(loopStatement)
206
- replacer = ReplaceIterator(self.iteratorName, iterationIndex)
207
- newStatement = replacer.visit(copiedStatement)
208
- ast.fix_missing_locations(newStatement)
209
- newStatements.append(newStatement)
210
- # Optionally, process the orelse block.
211
- if node.orelse:
212
- for elseStmt in node.orelse:
213
- visitedElse = self.visit(elseStmt)
214
- if isinstance(visitedElse, list):
215
- newStatements.extend(visitedElse)
216
- else:
217
- newStatements.append(visitedElse)
218
- return newStatements
219
- return [cast(ast.stmt, self.generic_visit(node))]
220
-
221
- newFunctionDef = WhileLoopUnroller(iteratorName, iterationsTotal).visit(FunctionDefTarget)
222
- ast.fix_missing_locations(newFunctionDef)
223
- return newFunctionDef
224
-
225
- def makeLauncherBasicJobNumba(callableTarget: str, pathFilenameFoldsTotal: pathlib.Path) -> ast.Module:
226
- linesLaunch = f"""
227
- if __name__ == '__main__':
228
- import time
229
- timeStart = time.perf_counter()
230
- foldsTotal = {callableTarget}()
231
- print(foldsTotal, time.perf_counter() - timeStart)
232
- writeStream = open('{pathFilenameFoldsTotal.as_posix()}', 'w')
233
- writeStream.write(str(foldsTotal))
234
- writeStream.close()
235
- """
236
- return ast.parse(linesLaunch)
237
-
238
- def makeFunctionDef(astModule: ast.Module, callableTarget: str, parametersNumba: Optional[ParametersNumba]=None, inlineCallables: Optional[bool]=False, unpackArrays: Optional[bool]=False, allImports: Optional[UniversalImportTracker]=None) -> Tuple[ast.FunctionDef, UniversalImportTracker]:
239
- if allImports is None:
240
- allImports = UniversalImportTracker()
241
- for statement in astModule.body:
242
- if isinstance(statement, (ast.Import, ast.ImportFrom)):
243
- allImports.addAst(statement)
244
-
245
- if inlineCallables:
246
- dictionaryFunctionDef = {statement.name: statement for statement in astModule.body if isinstance(statement, ast.FunctionDef)}
247
- callableInlinerWorkhorse = RecursiveInliner(dictionaryFunctionDef)
248
- # NOTE the inliner assumes each function is not called more than once
249
- # TODO change the inliner to handle multiple calls to the same function
250
- FunctionDefTarget = callableInlinerWorkhorse.inlineFunctionBody(callableTarget)
251
- else:
252
- FunctionDefTarget = next((node for node in astModule.body if isinstance(node, ast.FunctionDef) and node.name == callableTarget), None)
253
- if not FunctionDefTarget:
254
- raise ValueError(f"Could not find function {callableTarget} in source code")
255
-
256
- ast.fix_missing_locations(FunctionDefTarget)
257
-
258
- FunctionDefTarget, allImports = decorateCallableWithNumba(FunctionDefTarget, allImports, parametersNumba)
259
-
260
- # NOTE vestigial hardcoding
261
- if unpackArrays:
262
- for tupleUnpack in [(indexMy, 'my'), (indexTrack, 'track')]:
263
- unpacker = UnpackArrays(*tupleUnpack)
264
- FunctionDefTarget = cast(ast.FunctionDef, unpacker.visit(FunctionDefTarget))
265
- ast.fix_missing_locations(FunctionDefTarget)
266
-
267
- return FunctionDefTarget, allImports
268
-
269
- def decorateCallableWithNumba(FunctionDefTarget: ast.FunctionDef, allImports: UniversalImportTracker, parametersNumba: Optional[ParametersNumba]=None) -> Tuple[ast.FunctionDef, UniversalImportTracker]:
270
- def Z0Z_UnhandledDecorators(astCallable: ast.FunctionDef) -> ast.FunctionDef:
271
- # TODO: more explicit handling of decorators. I'm able to ignore this because I know `algorithmSource` doesn't have any decorators.
272
- for decoratorItem in astCallable.decorator_list.copy():
273
- import warnings
274
- astCallable.decorator_list.remove(decoratorItem)
275
- warnings.warn(f"Removed decorator {ast.unparse(decoratorItem)} from {astCallable.name}")
276
- return astCallable
277
-
278
- def make_arg4parameter(signatureElement: ast.arg) -> ast.Subscript | None:
279
- if isinstance(signatureElement.annotation, ast.Subscript) and isinstance(signatureElement.annotation.slice, ast.Tuple):
280
- annotationShape = signatureElement.annotation.slice.elts[0]
281
- if isinstance(annotationShape, ast.Subscript) and isinstance(annotationShape.slice, ast.Tuple):
282
- shapeAsListSlices = [ast.Slice() for axis in range(len(annotationShape.slice.elts))]
283
- shapeAsListSlices[-1] = ast.Slice(step=ast.Constant(value=1))
284
- shapeAST = ast.Tuple(elts=list(shapeAsListSlices), ctx=ast.Load())
285
- else:
286
- shapeAST = ast.Slice(step=ast.Constant(value=1))
287
-
288
- annotationDtype = signatureElement.annotation.slice.elts[1]
289
- if (isinstance(annotationDtype, ast.Subscript) and isinstance(annotationDtype.slice, ast.Attribute)):
290
- datatypeAST = annotationDtype.slice.attr
291
- else:
292
- datatypeAST = None
293
-
294
- ndarrayName = signatureElement.arg
295
- Z0Z_hacky_dtype = hackSSOTdatatype(ndarrayName)
296
- datatype_attr = datatypeAST or Z0Z_hacky_dtype
297
- allImports.addImportFromStr(datatypeModuleDecorator, datatype_attr)
298
- datatypeNumba = ast.Name(id=datatype_attr, ctx=ast.Load())
299
-
300
- return ast.Subscript(value=datatypeNumba, slice=shapeAST, ctx=ast.Load())
301
- return
302
-
303
- datatypeModuleDecorator = Z0Z_getDatatypeModuleScalar()
304
- list_argsDecorator: Sequence[ast.expr] = []
305
-
306
- list_arg4signature_or_function: List[ast.expr] = []
307
- for parameter in FunctionDefTarget.args.args:
308
- signatureElement = make_arg4parameter(parameter)
309
- if signatureElement:
310
- list_arg4signature_or_function.append(signatureElement)
311
-
312
- if FunctionDefTarget.returns and isinstance(FunctionDefTarget.returns, ast.Name):
313
- theReturn: ast.Name = FunctionDefTarget.returns
314
- list_argsDecorator = [cast(ast.expr, ast.Call(func=ast.Name(id=theReturn.id, ctx=ast.Load())
315
- , args=list_arg4signature_or_function if list_arg4signature_or_function else [] , keywords=[] ) )]
316
- elif list_arg4signature_or_function:
317
- list_argsDecorator = [cast(ast.expr, ast.Tuple(elts=list_arg4signature_or_function, ctx=ast.Load()))]
318
-
319
- for decorator in FunctionDefTarget.decorator_list.copy():
320
- if thisIsAnyNumbaJitDecorator(decorator):
321
- decorator = cast(ast.Call, decorator)
322
- if parametersNumba is None:
323
- parametersNumbaSherpa = Then.copy_astCallKeywords(decorator)
324
- if (HunterIsSureThereAreBetterWaysToDoThis := True):
325
- if parametersNumbaSherpa:
326
- parametersNumba = cast(ParametersNumba, parametersNumbaSherpa)
327
- FunctionDefTarget.decorator_list.remove(decorator)
328
-
329
- FunctionDefTarget = Z0Z_UnhandledDecorators(FunctionDefTarget)
330
- if parametersNumba is None:
331
- parametersNumba = parametersNumbaDEFAULT
332
- listDecoratorKeywords = [ast.keyword(arg=parameterName, value=ast.Constant(value=parameterValue)) for parameterName, parameterValue in parametersNumba.items()]
333
-
334
- decoratorModule = Z0Z_getDatatypeModuleScalar()
335
- decoratorCallable = Z0Z_getDecoratorCallable()
336
- allImports.addImportFromStr(decoratorModule, decoratorCallable)
337
- astDecorator = Then.make_astCall(decoratorCallable, list_argsDecorator, listDecoratorKeywords, None)
338
-
339
- FunctionDefTarget.decorator_list = [astDecorator]
340
- return FunctionDefTarget, allImports