mapFolding 0.4.2__py3-none-any.whl → 0.4.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  from mapFolding import (
2
2
  computationState,
3
3
  EnumIndices,
4
- formatModuleNameDEFAULT,
4
+ formatFilenameModuleDEFAULT,
5
5
  FREAKOUT,
6
6
  getAlgorithmDispatcher,
7
7
  getAlgorithmSource,
@@ -36,7 +36,7 @@ from numpy import integer
36
36
  from numpy.typing import NDArray
37
37
  from types import ModuleType
38
38
  from typing import Any, Callable, cast, Dict, List, Optional, Sequence, Set, Tuple, Type, Union
39
- from Z0Z_tools import autoDecodingRLE
39
+ from Z0Z_tools import autoDecodingRLE, updateExtendPolishDictionaryLists
40
40
  import ast
41
41
  import autoflake
42
42
  import collections
@@ -49,9 +49,41 @@ import numpy
49
49
  import os
50
50
  import pathlib
51
51
  import python_minifier
52
+ import warnings
52
53
 
53
54
  youOughtaKnow = collections.namedtuple('youOughtaKnow', ['callableSynthesized', 'pathFilenameForMe', 'astForCompetentProgrammers'])
54
55
 
56
+ # idk how to use this
57
+ class ASTBodyTransformer:
58
+ """
59
+ A helper class to apply multiple transformations on an AST FunctionDef's body.
60
+ This abstraction eliminates the need to write repetitive loops for removals,
61
+ replacements, or insertions.
62
+ """
63
+ def __init__(self, functionDefinition: ast.FunctionDef) -> None:
64
+ self.functionDefinition = functionDefinition
65
+
66
+ def replaceIn_body(self, predicate: Callable[[ast.stmt], bool], replacementBuilder: Callable[[ast.stmt], Optional[ast.stmt]]) -> None:
67
+ newBody: List[ast.stmt] = []
68
+ for statement in self.functionDefinition.body:
69
+ if predicate(statement):
70
+ replacementStatement = replacementBuilder(statement)
71
+ if replacementStatement is not None:
72
+ newBody.append(replacementStatement)
73
+ else:
74
+ newBody.append(statement)
75
+ self.functionDefinition.body = newBody
76
+
77
+ def atIndexInsert(self, index: int, statement: ast.stmt) -> None:
78
+ self.functionDefinition.body.insert(index, statement)
79
+
80
+ def removeAllOf(self, predicate: Callable[[ast.stmt], bool]) -> None:
81
+ self.replaceIn_body(predicate, lambda stmt: None)
82
+
83
+ def Z0Z_apply(self) -> ast.FunctionDef:
84
+ ast.fix_missing_locations(self.functionDefinition)
85
+ return self.functionDefinition
86
+
55
87
  # Generic
56
88
  class ifThis:
57
89
  """Generic AST node predicate builder."""
@@ -71,10 +103,27 @@ class ifThis:
71
103
  def isCallWithName(callableName: str) -> Callable[[ast.AST], bool]:
72
104
  return lambda node: (isinstance(node, ast.Call) and isinstance(node.func, ast.Name) and node.func.id == callableName)
73
105
 
106
+ @staticmethod
107
+ def isAssignTarget(identifier: str):
108
+ return lambda node: (isinstance(node, ast.Assign)
109
+ and node.targets
110
+ and isinstance(node.targets[0], ast.Name)
111
+ and node.targets[0].id == identifier)
112
+
74
113
  @staticmethod
75
114
  def anyOf(*predicates: Callable[[ast.AST], bool]) -> Callable[[ast.AST], bool]:
76
115
  return lambda node: any(pred(node) for pred in predicates)
77
116
 
117
+ @staticmethod
118
+ def isUnpackingAnArray(identifier:str):
119
+ return lambda node: (isinstance(node, ast.Assign)
120
+ and isinstance(node.targets[0], ast.Name)
121
+ and isinstance(node.value, ast.Subscript)
122
+ and isinstance(node.value.value, ast.Name)
123
+ and node.value.value.id == identifier
124
+ and isinstance(node.value.slice, ast.Attribute)
125
+ )
126
+
78
127
  class Then:
79
128
  """Generic actions."""
80
129
  @staticmethod
@@ -103,9 +152,8 @@ class NodeReplacer(ast.NodeTransformer):
103
152
  None from the replacement builder indicates that the node should be removed.
104
153
 
105
154
  Attributes:
106
- findMe (Callable[[ast.AST], bool]): A function that determines whether a node should be replaced.
107
- nodeReplacementBuilder (Callable[[ast.AST], Optional[ast.AST]]): A function that returns a new node
108
- or None to remove the node.
155
+ findMe: A function that determines whether a node should be replaced.
156
+ nodeReplacementBuilder: A function that returns a new node or None to remove the node.
109
157
 
110
158
  Methods:
111
159
  visit(node: ast.AST) -> Optional[ast.AST]:
@@ -142,19 +190,42 @@ class UniversalImportTracker:
142
190
  self.setImport.add(alias.name)
143
191
  elif isinstance(astImport_, ast.ImportFrom):
144
192
  if astImport_.module is not None:
145
- self.dictionaryImportFrom[astImport_.module].update(alias.name for alias in astImport_.names)
193
+ self.dictionaryImportFrom[astImport_.module].update((alias.name, alias.asname) for alias in astImport_.names)
146
194
 
147
- def addImportFromStr(self, module: str, name: str) -> None:
148
- self.dictionaryImportFrom[module].add(name)
195
+ def addImportStr(self, module: str) -> None:
196
+ self.setImport.add(module)
149
197
 
150
- def addImportStr(self, name: str) -> None:
151
- self.setImport.add(name)
198
+ def addImportFromStr(self, module: str, name: str, asname: Optional[str] = None) -> None:
199
+ self.dictionaryImportFrom[module].add((name, asname))
152
200
 
153
201
  def makeListAst(self) -> List[Union[ast.ImportFrom, ast.Import]]:
154
- listAstImportFrom = [ast.ImportFrom(module=module, names=[ast.alias(name=name, asname=None)], level=0) for module, names in self.dictionaryImportFrom.items() for name in names]
155
- listAstImport = [ast.Import(names=[ast.alias(name=name, asname=None)]) for name in self.setImport]
202
+ listAstImportFrom = []
203
+ for module, setOfNameTuples in sorted(self.dictionaryImportFrom.items()):
204
+ listAliases = []
205
+ for name, asname in setOfNameTuples:
206
+ listAliases.append(ast.alias(name=name, asname=asname))
207
+ listAstImportFrom.append(ast.ImportFrom(module=module, names=listAliases, level=0))
208
+
209
+ listAstImport = [ast.Import(names=[ast.alias(name=name, asname=None)]) for name in sorted(self.setImport)]
156
210
  return listAstImportFrom + listAstImport
157
211
 
212
+ def update(self, *fromTracker: 'UniversalImportTracker') -> None:
213
+ """
214
+ Update this tracker with imports from one or more other trackers.
215
+
216
+ Parameters:
217
+ *fromTracker: One or more UniversalImportTracker objects to merge from.
218
+ """
219
+ # Merge all import-from dictionaries
220
+ dictionaryMerged = updateExtendPolishDictionaryLists(self.dictionaryImportFrom, *(tracker.dictionaryImportFrom for tracker in fromTracker), destroyDuplicates=True, reorderLists=True)
221
+
222
+ # Convert lists back to sets for each module's imports
223
+ self.dictionaryImportFrom = {module: set(listNames) for module, listNames in dictionaryMerged.items()}
224
+
225
+ # Update direct imports
226
+ for tracker in fromTracker:
227
+ self.setImport.update(tracker.setImport)
228
+
158
229
  # Intricate and specialized
159
230
  class RecursiveInliner(ast.NodeTransformer):
160
231
  """
@@ -64,6 +64,7 @@ def writeJobNumba(mapShape: Sequence[int]
64
64
  pythonSource = inspect.getsource(algorithmSource)
65
65
  astModule = ast.parse(pythonSource)
66
66
  setFunctionDef = {statement for statement in astModule.body if isinstance(statement, ast.FunctionDef)}
67
+
67
68
  if not callableTarget:
68
69
  if len(setFunctionDef) == 1:
69
70
  FunctionDefTarget = setFunctionDef.pop()
@@ -71,7 +72,8 @@ def writeJobNumba(mapShape: Sequence[int]
71
72
  else:
72
73
  raise ValueError(f"I did not receive a `callableTarget` and {algorithmSource.__name__=} has more than one callable: {setFunctionDef}. Please select one.")
73
74
  else:
74
- FunctionDefTarget = setFunctionDef.pop() if callableTarget in {statement.name for statement in setFunctionDef} else None
75
+ listFunctionDefTarget = [statement for statement in setFunctionDef if statement.name == callableTarget]
76
+ FunctionDefTarget = listFunctionDefTarget[0] if listFunctionDefTarget else None
75
77
  if not FunctionDefTarget: raise ValueError(f"I received `{callableTarget=}` and {algorithmSource.__name__=}, but I could not find that function in that source.")
76
78
 
77
79
  # NOTE `allImports` is a complementary container to `FunctionDefTarget`; the `FunctionDefTarget` cannot track its own imports very well.
@@ -86,13 +88,15 @@ def writeJobNumba(mapShape: Sequence[int]
86
88
  case 'my':
87
89
  FunctionDefTarget, allImports = findAndReplaceArraySubscriptIn_body(FunctionDefTarget, pirateScowl.arg, stateJob[pirateScowl.arg], ['taskIndex', 'dimensionsTotal'], allImports)
88
90
  case 'track':
89
- FunctionDefTarget, allImports = findAndReplaceArrayIn_body(FunctionDefTarget, pirateScowl.arg, stateJob[pirateScowl.arg], allImports)
91
+ FunctionDefTarget, allImports = findAndReplaceTrackArrayIn_body(FunctionDefTarget, pirateScowl.arg, stateJob[pirateScowl.arg], allImports)
90
92
  case 'connectionGraph':
91
93
  FunctionDefTarget, allImports = insertArrayIn_body(FunctionDefTarget, pirateScowl.arg, stateJob[pirateScowl.arg], allImports)
92
94
  case 'gapsWhere':
93
95
  FunctionDefTarget, allImports = insertArrayIn_body(FunctionDefTarget, pirateScowl.arg, stateJob[pirateScowl.arg], allImports)
94
96
  case 'foldGroups':
95
97
  FunctionDefTarget = removeAssignTargetFrom_body(FunctionDefTarget, pirateScowl.arg)
98
+ # FunctionDefTarget, allImports = insertArrayIn_body(FunctionDefTarget, pirateScowl.arg, stateJob[pirateScowl.arg], allImports)
99
+ # continue
96
100
  FunctionDefTarget.args.args.remove(pirateScowl)
97
101
 
98
102
  # NOTE replace identifiers with static values with their values
@@ -110,8 +114,6 @@ def writeJobNumba(mapShape: Sequence[int]
110
114
  FunctionDefTarget, allImports = insertReturnStatementIn_body(FunctionDefTarget, stateJob['foldGroups'], allImports)
111
115
 
112
116
  # NOTE add the perfect decorator
113
- datatype = hackSSOTdatatype(Z0Z_identifierCountFolds)
114
- FunctionDefTarget.returns = ast.Name(id=datatype, ctx=ast.Load())
115
117
  FunctionDefTarget, allImports = decorateCallableWithNumba(FunctionDefTarget, allImports, parametersNumba)
116
118
  if thisIsNumbaDotJit(FunctionDefTarget.decorator_list[0]):
117
119
  astCall = cast(ast.Call, FunctionDefTarget.decorator_list[0])
@@ -124,21 +126,7 @@ def writeJobNumba(mapShape: Sequence[int]
124
126
  ast.fix_missing_locations(astModule)
125
127
  pythonSource = ast.unparse(astModule)
126
128
  pythonSource = autoflake.fix_code(pythonSource, ['mapFolding', 'numba', 'numpy'])
127
- pythonSource = python_minifier.minify(pythonSource, remove_annotations = False,
128
- remove_pass = False,
129
- remove_literal_statements = False,
130
- combine_imports = True,
131
- hoist_literals = False,
132
- rename_locals = False,
133
- rename_globals = False,
134
- remove_object_base = False,
135
- convert_posargs_to_args = False,
136
- preserve_shebang = True,
137
- remove_asserts = False,
138
- remove_debug = False,
139
- remove_explicit_return_none = False,
140
- remove_builtin_exception_brackets = False,
141
- constant_folding = False)
129
+ # pythonSource = python_minifier.minify(pythonSource, remove_annotations = False, remove_pass = False, remove_literal_statements = False, combine_imports = True, hoist_literals = False, rename_locals = False, rename_globals = False, remove_object_base = False, convert_posargs_to_args = False, preserve_shebang = True, remove_asserts = False, remove_debug = False, remove_explicit_return_none = False, remove_builtin_exception_brackets = False, constant_folding = False)
142
130
 
143
131
  # NOTE put on disk
144
132
  if pathFilenameWriteJob is None:
@@ -155,17 +143,18 @@ def writeJobNumba(mapShape: Sequence[int]
155
143
 
156
144
  if __name__ == '__main__':
157
145
  mapShape = [5,5]
158
- from mapFolding.syntheticModules import numba_countSequential
159
- algorithmSource: ModuleType = numba_countSequential
146
+ from mapFolding.syntheticModules import numbaCount
147
+ algorithmSource: ModuleType = numbaCount
160
148
 
161
- callableTarget = None
149
+ callableTarget = 'countSequential'
162
150
 
163
151
  parametersNumba = parametersNumbaDEFAULT
152
+ parametersNumba['boundscheck'] = True
164
153
 
165
154
  pathFilenameWriteJob = None
166
155
 
167
156
  setDatatypeFoldsTotal('int64', sourGrapes=True)
168
- setDatatypeElephino('uint8', sourGrapes=True)
157
+ setDatatypeElephino('int16', sourGrapes=True)
169
158
  setDatatypeLeavesTotal('uint8', sourGrapes=True)
170
159
  Z0Z_setDatatypeModuleScalar('numba')
171
160
  Z0Z_setDecoratorCallable('jit')
@@ -4,42 +4,82 @@ everything I am doing. I would rather benefit from humanity's
4
4
  collective wisdom."""
5
5
  from mapFolding.someAssemblyRequired.synthesizeNumba import *
6
6
 
7
- def makeFlowNumbaOptimized(listCallablesInline: List[str], callableDispatcher: Optional[bool] = False, algorithmSource: Optional[ModuleType] = None, relativePathWrite: Optional[pathlib.Path] = None, formatFilenameWrite: Optional[str] = None) -> List[youOughtaKnow]:
8
- if relativePathWrite and relativePathWrite.is_absolute():
9
- raise ValueError("The path to write the module must be relative to the root of the package.")
10
- if not algorithmSource:
11
- algorithmSource = getAlgorithmSource()
7
+ def getFunctionDef(algorithmSource: ModuleType, *arguments, **keywordArguments) -> Tuple[ast.FunctionDef, UniversalImportTracker]:
8
+ pythonSource = inspect.getsource(algorithmSource)
9
+ astModule: ast.Module = ast.parse(pythonSource, type_comments=True)
10
+ FunctionDefTarget, allImports = makeFunctionDef(astModule, *arguments, **keywordArguments)
11
+ return FunctionDefTarget, allImports
12
12
 
13
- listStuffYouOughtaKnow: List[youOughtaKnow] = []
13
+ def makePythonSource(listFunctionDefs: List[ast.FunctionDef], listAstImports: List[ast.Import|ast.ImportFrom], additional_imports: List[str]) -> str:
14
+ astModule = ast.Module(body=cast(List[ast.stmt], listAstImports + listFunctionDefs), type_ignores=[])
15
+ ast.fix_missing_locations(astModule)
16
+ pythonSource = ast.unparse(astModule)
17
+ if not pythonSource: raise FREAKOUT
18
+ pythonSource = autoflake.fix_code(pythonSource, additional_imports)
19
+ return pythonSource
20
+
21
+ def writePythonAsModule(pythonSource: str, listCallableSynthesized: List[str], relativePathWrite: Optional[pathlib.Path], filenameWrite: Optional[str], formatFilenameWrite: Optional[str]) -> List[youOughtaKnow]:
22
+ pathFilename = None
23
+ if not relativePathWrite:
24
+ pathWrite = getPathSyntheticModules()
25
+ else:
26
+ pathWrite = getPathPackage() / relativePathWrite
14
27
 
15
- def doThisStuff(callableTarget: str, parametersNumba: Optional[ParametersNumba], inlineCallables: bool, unpackArrays: bool, allImports: Optional[UniversalImportTracker], relativePathWrite: Optional[pathlib.Path], formatFilenameWrite: Optional[str]) -> youOughtaKnow:
16
- pythonSource = inspect.getsource(algorithmSource)
17
- pythonSource = makeAstModuleForOneCallable(pythonSource, callableTarget, parametersNumba, inlineCallables, unpackArrays, allImports)
18
- if not pythonSource: raise FREAKOUT
19
- pythonSource = autoflake.fix_code(pythonSource, ['mapFolding', 'numba', 'numpy'])
28
+ if not formatFilenameWrite:
29
+ formatFilenameWrite = formatFilenameModuleDEFAULT
20
30
 
21
- if not relativePathWrite:
22
- pathWrite = getPathSyntheticModules()
31
+ if not filenameWrite:
32
+ if len(listCallableSynthesized) == 1:
33
+ callableTarget = listCallableSynthesized[0]
23
34
  else:
24
- pathWrite = getPathPackage() / relativePathWrite
25
- if not formatFilenameWrite:
26
- formatFilenameWrite = formatModuleNameDEFAULT + '.py'
27
- pathFilename = pathWrite / formatFilenameWrite.format(callableTarget=callableTarget)
35
+ callableTarget = 'count'
36
+ filenameWrite = formatFilenameWrite.format(callableTarget=callableTarget)
37
+ else:
38
+ if not filenameWrite.endswith('.py'):
39
+ warnings.warn(f"Filename {filenameWrite=} does not end with '.py'.")
28
40
 
29
- pathFilename.write_text(pythonSource)
41
+ pathFilename = pathWrite / filenameWrite
30
42
 
31
- howIsThisStillAThing = getPathPackage().parent
32
- dumbassPythonNamespace = pathFilename.relative_to(howIsThisStillAThing).with_suffix('').parts
33
- ImaModule = '.'.join(dumbassPythonNamespace)
43
+ pathFilename.write_text(pythonSource)
44
+
45
+ howIsThisStillAThing = getPathPackage().parent
46
+ dumbassPythonNamespace = pathFilename.relative_to(howIsThisStillAThing).with_suffix('').parts
47
+ ImaModule = '.'.join(dumbassPythonNamespace)
48
+
49
+ listStuffYouOughtaKnow: List[youOughtaKnow] = []
50
+
51
+ for callableTarget in listCallableSynthesized:
34
52
  astImportFrom = ast.ImportFrom(module=ImaModule, names=[ast.alias(name=callableTarget, asname=None)], level=0)
53
+ stuff = youOughtaKnow(callableSynthesized=callableTarget, pathFilenameForMe=pathFilename, astForCompetentProgrammers=astImportFrom)
54
+ listStuffYouOughtaKnow.append(stuff)
35
55
 
36
- return youOughtaKnow(callableSynthesized=callableTarget, pathFilenameForMe=pathFilename, astForCompetentProgrammers=astImportFrom)
56
+ return listStuffYouOughtaKnow
37
57
 
58
+ def makeFlowNumbaOptimized(listCallablesInline: List[str]
59
+ , callableDispatcher: Optional[bool] = False
60
+ , algorithmSource: Optional[ModuleType] = None
61
+ , relativePathWrite: Optional[pathlib.Path] = None
62
+ , filenameModuleWrite: Optional[str] = None
63
+ , formatFilenameWrite: Optional[str] = None
64
+ ) -> List[youOughtaKnow]:
65
+ if relativePathWrite and relativePathWrite.is_absolute():
66
+ raise ValueError("The path to write the module must be relative to the root of the package.")
67
+ if not algorithmSource:
68
+ algorithmSource = getAlgorithmSource()
69
+
70
+ Z0Z_filenameModuleWrite = 'numbaCount.py'
71
+
72
+ listStuffYouOughtaKnow: List[youOughtaKnow] = []
73
+ additional_imports = ['mapFolding', 'numba', 'numpy']
74
+
75
+ listFunctionDefs: List[ast.FunctionDef] = []
76
+ allImportsModule = UniversalImportTracker()
38
77
  for callableTarget in listCallablesInline:
39
78
  parametersNumba = None
40
79
  inlineCallables = True
41
80
  unpackArrays = False
42
81
  allImports = None
82
+ filenameWrite = None
43
83
  match callableTarget:
44
84
  case 'countParallel':
45
85
  parametersNumba = parametersNumbaSuperJitParallel
@@ -48,7 +88,17 @@ def makeFlowNumbaOptimized(listCallablesInline: List[str], callableDispatcher: O
48
88
  unpackArrays = True
49
89
  case 'countInitialize':
50
90
  parametersNumba = parametersNumbaDEFAULT
51
- listStuffYouOughtaKnow.append(doThisStuff(callableTarget, parametersNumba, inlineCallables, unpackArrays, allImports, relativePathWrite, formatFilenameWrite))
91
+ FunctionDefTarget, allImports = getFunctionDef(algorithmSource, callableTarget, parametersNumba, inlineCallables, unpackArrays, allImports)
92
+ listFunctionDefs.append(FunctionDefTarget)
93
+ allImportsModule.update(allImports)
94
+
95
+ listAstImports = allImportsModule.makeListAst()
96
+ pythonSource = makePythonSource(listFunctionDefs, listAstImports, additional_imports)
97
+
98
+ filenameWrite = filenameModuleWrite or Z0Z_filenameModuleWrite
99
+
100
+ listStuff = writePythonAsModule(pythonSource, listCallablesInline, relativePathWrite, filenameWrite, formatFilenameWrite)
101
+ listStuffYouOughtaKnow.extend(listStuff)
52
102
 
53
103
  if callableDispatcher:
54
104
  callableTarget = getAlgorithmDispatcher().__name__
@@ -56,22 +106,24 @@ def makeFlowNumbaOptimized(listCallablesInline: List[str], callableDispatcher: O
56
106
  inlineCallables = False
57
107
  unpackArrays = False
58
108
  allImports = UniversalImportTracker()
109
+ filenameWrite = None
59
110
  for stuff in listStuffYouOughtaKnow:
60
111
  statement = stuff.astForCompetentProgrammers
61
112
  if isinstance(statement, (ast.Import, ast.ImportFrom)):
62
113
  allImports.addAst(statement)
114
+ FunctionDefTarget, allImports = getFunctionDef(algorithmSource, callableTarget, parametersNumba, inlineCallables, unpackArrays, allImports)
115
+ listAstImports = allImports.makeListAst()
116
+
117
+ pythonSource = makePythonSource([FunctionDefTarget], listAstImports, additional_imports)
63
118
 
64
- listStuffYouOughtaKnow.append(doThisStuff(callableTarget, parametersNumba, inlineCallables, unpackArrays, allImports, relativePathWrite, formatFilenameWrite))
119
+ listStuff = writePythonAsModule(pythonSource, [callableTarget], relativePathWrite, filenameWrite, formatFilenameWrite)
120
+ listStuffYouOughtaKnow.extend(listStuff)
65
121
 
66
122
  return listStuffYouOughtaKnow
67
123
 
68
124
  if __name__ == '__main__':
69
- setDatatypeModule('numpy', sourGrapes=True)
70
- setDatatypeFoldsTotal('int64', sourGrapes=True)
71
- setDatatypeElephino('uint8', sourGrapes=True)
72
- setDatatypeLeavesTotal('uint8', sourGrapes=True)
73
- Z0Z_setDatatypeModuleScalar('numba')
74
- Z0Z_setDecoratorCallable('jit')
125
+ # Z0Z_setDatatypeModuleScalar('numba')
126
+ # Z0Z_setDecoratorCallable('jit')
75
127
  listCallablesInline: List[str] = ['countInitialize', 'countParallel', 'countSequential']
76
128
  callableDispatcher = True
77
129
  makeFlowNumbaOptimized(listCallablesInline, callableDispatcher)
@@ -0,0 +1,158 @@
1
+ from mapFolding import indexMy, indexTrack
2
+ from numba import jit, int64, prange, uint16
3
+ from numpy import ndarray, dtype, integer
4
+ from typing import Tuple, Any
5
+
6
+ @jit((uint16[:, :, ::1], uint16[::1], uint16[::1], uint16[:, ::1]), _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)
7
+ def countInitialize(connectionGraph: ndarray[Tuple[int, int, int], dtype[integer[Any]]], gapsWhere: ndarray[Tuple[int], dtype[integer[Any]]], my: ndarray[Tuple[int], dtype[integer[Any]]], track: ndarray[Tuple[int, int], dtype[integer[Any]]]) -> None:
8
+ while my[indexMy.leaf1ndex.value] > 0:
9
+ if my[indexMy.leaf1ndex.value] <= 1 or track[indexTrack.leafBelow.value, 0] == 1:
10
+ my[indexMy.dimensionsUnconstrained.value] = my[indexMy.dimensionsTotal.value]
11
+ my[indexMy.gap1ndexCeiling.value] = track[indexTrack.gapRangeStart.value, my[indexMy.leaf1ndex.value] - 1]
12
+ my[indexMy.indexDimension.value] = 0
13
+ while my[indexMy.indexDimension.value] < my[indexMy.dimensionsTotal.value]:
14
+ if connectionGraph[my[indexMy.indexDimension.value], my[indexMy.leaf1ndex.value], my[indexMy.leaf1ndex.value]] == my[indexMy.leaf1ndex.value]:
15
+ my[indexMy.dimensionsUnconstrained.value] -= 1
16
+ else:
17
+ my[indexMy.leafConnectee.value] = connectionGraph[my[indexMy.indexDimension.value], my[indexMy.leaf1ndex.value], my[indexMy.leaf1ndex.value]]
18
+ while my[indexMy.leafConnectee.value] != my[indexMy.leaf1ndex.value]:
19
+ gapsWhere[my[indexMy.gap1ndexCeiling.value]] = my[indexMy.leafConnectee.value]
20
+ if track[indexTrack.countDimensionsGapped.value, my[indexMy.leafConnectee.value]] == 0:
21
+ my[indexMy.gap1ndexCeiling.value] += 1
22
+ track[indexTrack.countDimensionsGapped.value, my[indexMy.leafConnectee.value]] += 1
23
+ my[indexMy.leafConnectee.value] = connectionGraph[my[indexMy.indexDimension.value], my[indexMy.leaf1ndex.value], track[indexTrack.leafBelow.value, my[indexMy.leafConnectee.value]]]
24
+ my[indexMy.indexDimension.value] += 1
25
+ if not my[indexMy.dimensionsUnconstrained.value]:
26
+ my[indexMy.indexLeaf.value] = 0
27
+ while my[indexMy.indexLeaf.value] < my[indexMy.leaf1ndex.value]:
28
+ gapsWhere[my[indexMy.gap1ndexCeiling.value]] = my[indexMy.indexLeaf.value]
29
+ my[indexMy.gap1ndexCeiling.value] += 1
30
+ my[indexMy.indexLeaf.value] += 1
31
+ my[indexMy.indexMiniGap.value] = my[indexMy.gap1ndex.value]
32
+ while my[indexMy.indexMiniGap.value] < my[indexMy.gap1ndexCeiling.value]:
33
+ gapsWhere[my[indexMy.gap1ndex.value]] = gapsWhere[my[indexMy.indexMiniGap.value]]
34
+ if track[indexTrack.countDimensionsGapped.value, gapsWhere[my[indexMy.indexMiniGap.value]]] == my[indexMy.dimensionsUnconstrained.value]:
35
+ my[indexMy.gap1ndex.value] += 1
36
+ track[indexTrack.countDimensionsGapped.value, gapsWhere[my[indexMy.indexMiniGap.value]]] = 0
37
+ my[indexMy.indexMiniGap.value] += 1
38
+ if my[indexMy.leaf1ndex.value] > 0:
39
+ my[indexMy.gap1ndex.value] -= 1
40
+ track[indexTrack.leafAbove.value, my[indexMy.leaf1ndex.value]] = gapsWhere[my[indexMy.gap1ndex.value]]
41
+ track[indexTrack.leafBelow.value, my[indexMy.leaf1ndex.value]] = track[indexTrack.leafBelow.value, track[indexTrack.leafAbove.value, my[indexMy.leaf1ndex.value]]]
42
+ track[indexTrack.leafBelow.value, track[indexTrack.leafAbove.value, my[indexMy.leaf1ndex.value]]] = my[indexMy.leaf1ndex.value]
43
+ track[indexTrack.leafAbove.value, track[indexTrack.leafBelow.value, my[indexMy.leaf1ndex.value]]] = my[indexMy.leaf1ndex.value]
44
+ track[indexTrack.gapRangeStart.value, my[indexMy.leaf1ndex.value]] = my[indexMy.gap1ndex.value]
45
+ my[indexMy.leaf1ndex.value] += 1
46
+ if my[indexMy.gap1ndex.value] > 0:
47
+ return
48
+
49
+ @jit((uint16[:, :, ::1], int64[::1], uint16[::1], uint16[::1], uint16[:, ::1]), _nrt=True, boundscheck=False, cache=True, error_model='numpy', fastmath=True, forceinline=True, inline='always', looplift=False, no_cfunc_wrapper=True, no_cpython_wrapper=True, nopython=True, parallel=True)
50
+ def countParallel(connectionGraph: ndarray[Tuple[int, int, int], dtype[integer[Any]]], foldGroups: ndarray[Tuple[int], dtype[integer[Any]]], gapsWhere: ndarray[Tuple[int], dtype[integer[Any]]], my: ndarray[Tuple[int], dtype[integer[Any]]], track: ndarray[Tuple[int, int], dtype[integer[Any]]]) -> None:
51
+ gapsWherePARALLEL = gapsWhere.copy()
52
+ myPARALLEL = my.copy()
53
+ trackPARALLEL = track.copy()
54
+ taskDivisionsPrange = myPARALLEL[indexMy.taskDivisions.value]
55
+ for indexSherpa in prange(taskDivisionsPrange):
56
+ groupsOfFolds: int = 0
57
+ gapsWhere = gapsWherePARALLEL.copy()
58
+ my = myPARALLEL.copy()
59
+ track = trackPARALLEL.copy()
60
+ my[indexMy.taskIndex.value] = indexSherpa
61
+ while my[indexMy.leaf1ndex.value] > 0:
62
+ if my[indexMy.leaf1ndex.value] <= 1 or track[indexTrack.leafBelow.value, 0] == 1:
63
+ if my[indexMy.leaf1ndex.value] > foldGroups[-1]:
64
+ groupsOfFolds += 1
65
+ else:
66
+ my[indexMy.dimensionsUnconstrained.value] = my[indexMy.dimensionsTotal.value]
67
+ my[indexMy.gap1ndexCeiling.value] = track[indexTrack.gapRangeStart.value, my[indexMy.leaf1ndex.value] - 1]
68
+ my[indexMy.indexDimension.value] = 0
69
+ while my[indexMy.indexDimension.value] < my[indexMy.dimensionsTotal.value]:
70
+ if connectionGraph[my[indexMy.indexDimension.value], my[indexMy.leaf1ndex.value], my[indexMy.leaf1ndex.value]] == my[indexMy.leaf1ndex.value]:
71
+ my[indexMy.dimensionsUnconstrained.value] -= 1
72
+ else:
73
+ my[indexMy.leafConnectee.value] = connectionGraph[my[indexMy.indexDimension.value], my[indexMy.leaf1ndex.value], my[indexMy.leaf1ndex.value]]
74
+ while my[indexMy.leafConnectee.value] != my[indexMy.leaf1ndex.value]:
75
+ if my[indexMy.leaf1ndex.value] != my[indexMy.taskDivisions.value] or my[indexMy.leafConnectee.value] % my[indexMy.taskDivisions.value] == my[indexMy.taskIndex.value]:
76
+ gapsWhere[my[indexMy.gap1ndexCeiling.value]] = my[indexMy.leafConnectee.value]
77
+ if track[indexTrack.countDimensionsGapped.value, my[indexMy.leafConnectee.value]] == 0:
78
+ my[indexMy.gap1ndexCeiling.value] += 1
79
+ track[indexTrack.countDimensionsGapped.value, my[indexMy.leafConnectee.value]] += 1
80
+ my[indexMy.leafConnectee.value] = connectionGraph[my[indexMy.indexDimension.value], my[indexMy.leaf1ndex.value], track[indexTrack.leafBelow.value, my[indexMy.leafConnectee.value]]]
81
+ my[indexMy.indexDimension.value] += 1
82
+ my[indexMy.indexMiniGap.value] = my[indexMy.gap1ndex.value]
83
+ while my[indexMy.indexMiniGap.value] < my[indexMy.gap1ndexCeiling.value]:
84
+ gapsWhere[my[indexMy.gap1ndex.value]] = gapsWhere[my[indexMy.indexMiniGap.value]]
85
+ if track[indexTrack.countDimensionsGapped.value, gapsWhere[my[indexMy.indexMiniGap.value]]] == my[indexMy.dimensionsUnconstrained.value]:
86
+ my[indexMy.gap1ndex.value] += 1
87
+ track[indexTrack.countDimensionsGapped.value, gapsWhere[my[indexMy.indexMiniGap.value]]] = 0
88
+ my[indexMy.indexMiniGap.value] += 1
89
+ while my[indexMy.leaf1ndex.value] > 0 and my[indexMy.gap1ndex.value] == track[indexTrack.gapRangeStart.value, my[indexMy.leaf1ndex.value] - 1]:
90
+ my[indexMy.leaf1ndex.value] -= 1
91
+ track[indexTrack.leafBelow.value, track[indexTrack.leafAbove.value, my[indexMy.leaf1ndex.value]]] = track[indexTrack.leafBelow.value, my[indexMy.leaf1ndex.value]]
92
+ track[indexTrack.leafAbove.value, track[indexTrack.leafBelow.value, my[indexMy.leaf1ndex.value]]] = track[indexTrack.leafAbove.value, my[indexMy.leaf1ndex.value]]
93
+ if my[indexMy.leaf1ndex.value] > 0:
94
+ my[indexMy.gap1ndex.value] -= 1
95
+ track[indexTrack.leafAbove.value, my[indexMy.leaf1ndex.value]] = gapsWhere[my[indexMy.gap1ndex.value]]
96
+ track[indexTrack.leafBelow.value, my[indexMy.leaf1ndex.value]] = track[indexTrack.leafBelow.value, track[indexTrack.leafAbove.value, my[indexMy.leaf1ndex.value]]]
97
+ track[indexTrack.leafBelow.value, track[indexTrack.leafAbove.value, my[indexMy.leaf1ndex.value]]] = my[indexMy.leaf1ndex.value]
98
+ track[indexTrack.leafAbove.value, track[indexTrack.leafBelow.value, my[indexMy.leaf1ndex.value]]] = my[indexMy.leaf1ndex.value]
99
+ track[indexTrack.gapRangeStart.value, my[indexMy.leaf1ndex.value]] = my[indexMy.gap1ndex.value]
100
+ my[indexMy.leaf1ndex.value] += 1
101
+ foldGroups[my[indexMy.taskIndex.value]] = groupsOfFolds
102
+
103
+ @jit((uint16[:, :, ::1], int64[::1], uint16[::1], uint16[::1], uint16[:, ::1]), _nrt=True, boundscheck=False, cache=True, error_model='numpy', fastmath=True, forceinline=True, inline='always', looplift=False, no_cfunc_wrapper=True, no_cpython_wrapper=True, nopython=True, parallel=False)
104
+ def countSequential(connectionGraph: ndarray[Tuple[int, int, int], dtype[integer[Any]]], foldGroups: ndarray[Tuple[int], dtype[integer[Any]]], gapsWhere: ndarray[Tuple[int], dtype[integer[Any]]], my: ndarray[Tuple[int], dtype[integer[Any]]], track: ndarray[Tuple[int, int], dtype[integer[Any]]]) -> None:
105
+ leafBelow = track[indexTrack.leafBelow.value]
106
+ gapRangeStart = track[indexTrack.gapRangeStart.value]
107
+ countDimensionsGapped = track[indexTrack.countDimensionsGapped.value]
108
+ leafAbove = track[indexTrack.leafAbove.value]
109
+ leaf1ndex = my[indexMy.leaf1ndex.value]
110
+ dimensionsUnconstrained = my[indexMy.dimensionsUnconstrained.value]
111
+ dimensionsTotal = my[indexMy.dimensionsTotal.value]
112
+ gap1ndexCeiling = my[indexMy.gap1ndexCeiling.value]
113
+ indexDimension = my[indexMy.indexDimension.value]
114
+ leafConnectee = my[indexMy.leafConnectee.value]
115
+ indexMiniGap = my[indexMy.indexMiniGap.value]
116
+ gap1ndex = my[indexMy.gap1ndex.value]
117
+ taskIndex = my[indexMy.taskIndex.value]
118
+ groupsOfFolds: int = 0
119
+ while leaf1ndex > 0:
120
+ if leaf1ndex <= 1 or leafBelow[0] == 1:
121
+ if leaf1ndex > foldGroups[-1]:
122
+ groupsOfFolds += 1
123
+ else:
124
+ dimensionsUnconstrained = dimensionsTotal
125
+ gap1ndexCeiling = gapRangeStart[leaf1ndex - 1]
126
+ indexDimension = 0
127
+ while indexDimension < dimensionsTotal:
128
+ leafConnectee = connectionGraph[indexDimension, leaf1ndex, leaf1ndex]
129
+ if leafConnectee == leaf1ndex:
130
+ dimensionsUnconstrained -= 1
131
+ else:
132
+ while leafConnectee != leaf1ndex:
133
+ gapsWhere[gap1ndexCeiling] = leafConnectee
134
+ if countDimensionsGapped[leafConnectee] == 0:
135
+ gap1ndexCeiling += 1
136
+ countDimensionsGapped[leafConnectee] += 1
137
+ leafConnectee = connectionGraph[indexDimension, leaf1ndex, leafBelow[leafConnectee]]
138
+ indexDimension += 1
139
+ indexMiniGap = gap1ndex
140
+ while indexMiniGap < gap1ndexCeiling:
141
+ gapsWhere[gap1ndex] = gapsWhere[indexMiniGap]
142
+ if countDimensionsGapped[gapsWhere[indexMiniGap]] == dimensionsUnconstrained:
143
+ gap1ndex += 1
144
+ countDimensionsGapped[gapsWhere[indexMiniGap]] = 0
145
+ indexMiniGap += 1
146
+ while leaf1ndex > 0 and gap1ndex == gapRangeStart[leaf1ndex - 1]:
147
+ leaf1ndex -= 1
148
+ leafBelow[leafAbove[leaf1ndex]] = leafBelow[leaf1ndex]
149
+ leafAbove[leafBelow[leaf1ndex]] = leafAbove[leaf1ndex]
150
+ if leaf1ndex > 0:
151
+ gap1ndex -= 1
152
+ leafAbove[leaf1ndex] = gapsWhere[gap1ndex]
153
+ leafBelow[leaf1ndex] = leafBelow[leafAbove[leaf1ndex]]
154
+ leafBelow[leafAbove[leaf1ndex]] = leaf1ndex
155
+ leafAbove[leafBelow[leaf1ndex]] = leaf1ndex
156
+ gapRangeStart[leaf1ndex] = gap1ndex
157
+ leaf1ndex += 1
158
+ foldGroups[taskIndex] = groupsOfFolds
@@ -1,17 +1,10 @@
1
- from mapFolding.syntheticModules.numba_countInitialize import countInitialize
2
- from mapFolding.syntheticModules.numba_countParallel import countParallel
3
- from mapFolding.syntheticModules.numba_countSequential import countSequential
4
1
  from mapFolding import indexMy
5
- from numba import int64
6
- from numba import jit
7
- from numba import uint8
8
- from numpy import dtype
9
- from numpy import ndarray
10
- from numpy import integer
11
- from typing import Tuple
12
- from typing import Any
2
+ from mapFolding.syntheticModules.numbaCount import countParallel, countSequential, countInitialize
3
+ from numba import jit, int64, uint16
4
+ from numpy import ndarray, dtype, integer
5
+ from typing import Tuple, Any
13
6
 
14
- @jit((uint8[:, :, ::1], int64[::1], uint8[::1], uint8[::1], uint8[::1], uint8[:, ::1]), _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)
7
+ @jit((uint16[:, :, ::1], int64[::1], uint16[::1], uint16[::1], uint16[::1], uint16[:, ::1]), _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)
15
8
  def doTheNeedful(connectionGraph: ndarray[Tuple[int, int, int], dtype[integer[Any]]], foldGroups: ndarray[Tuple[int], dtype[integer[Any]]], gapsWhere: ndarray[Tuple[int], dtype[integer[Any]]], mapShape: ndarray[Tuple[int], dtype[integer[Any]]], my: ndarray[Tuple[int], dtype[integer[Any]]], track: ndarray[Tuple[int, int], dtype[integer[Any]]]) -> None:
16
9
  countInitialize(connectionGraph, gapsWhere, my, track)
17
10
  if my[indexMy.taskDivisions.value] > 0: