mapFolding 0.2.5__tar.gz → 0.2.6__tar.gz
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-0.2.5 → mapfolding-0.2.6}/PKG-INFO +1 -1
- {mapfolding-0.2.5 → mapfolding-0.2.6}/mapFolding/babbage.py +6 -6
- {mapfolding-0.2.5 → mapfolding-0.2.6}/mapFolding/beDRY.py +40 -46
- mapfolding-0.2.6/mapFolding/importSelector.py +7 -0
- {mapfolding-0.2.5 → mapfolding-0.2.6}/mapFolding/lovelace.py +37 -37
- {mapfolding-0.2.5 → mapfolding-0.2.6}/mapFolding/someAssemblyRequired/inlineAfunction.py +1 -1
- {mapfolding-0.2.5 → mapfolding-0.2.6}/mapFolding/someAssemblyRequired/jobsAndTasks.py +2 -2
- {mapfolding-0.2.5 → mapfolding-0.2.6}/mapFolding/someAssemblyRequired/makeNumbaJob.py +54 -31
- {mapfolding-0.2.5 → mapfolding-0.2.6}/mapFolding/startHere.py +1 -1
- {mapfolding-0.2.5 → mapfolding-0.2.6}/mapFolding/theSSOT.py +9 -8
- {mapfolding-0.2.5 → mapfolding-0.2.6}/mapFolding.egg-info/PKG-INFO +1 -1
- {mapfolding-0.2.5 → mapfolding-0.2.6}/pyproject.toml +3 -3
- {mapfolding-0.2.5 → mapfolding-0.2.6}/tests/conftest.py +7 -9
- {mapfolding-0.2.5 → mapfolding-0.2.6}/tests/test_other.py +17 -3
- mapfolding-0.2.5/mapFolding/importSelector.py +0 -7
- {mapfolding-0.2.5 → mapfolding-0.2.6}/README.md +0 -0
- {mapfolding-0.2.5 → mapfolding-0.2.6}/mapFolding/__init__.py +0 -0
- {mapfolding-0.2.5 → mapfolding-0.2.6}/mapFolding/benchmarks/benchmarking.py +0 -0
- {mapfolding-0.2.5 → mapfolding-0.2.6}/mapFolding/oeis.py +0 -0
- {mapfolding-0.2.5 → mapfolding-0.2.6}/mapFolding/reference/flattened.py +0 -0
- {mapfolding-0.2.5 → mapfolding-0.2.6}/mapFolding/reference/hunterNumba.py +0 -0
- {mapfolding-0.2.5 → mapfolding-0.2.6}/mapFolding/reference/irvineJavaPort.py +0 -0
- {mapfolding-0.2.5 → mapfolding-0.2.6}/mapFolding/reference/jax.py +0 -0
- {mapfolding-0.2.5 → mapfolding-0.2.6}/mapFolding/reference/lunnan.py +0 -0
- {mapfolding-0.2.5 → mapfolding-0.2.6}/mapFolding/reference/lunnanNumpy.py +0 -0
- {mapfolding-0.2.5 → mapfolding-0.2.6}/mapFolding/reference/lunnanWhile.py +0 -0
- {mapfolding-0.2.5 → mapfolding-0.2.6}/mapFolding/reference/rotatedEntryPoint.py +0 -0
- {mapfolding-0.2.5 → mapfolding-0.2.6}/mapFolding/reference/total_countPlus1vsPlusN.py +0 -0
- {mapfolding-0.2.5 → mapfolding-0.2.6}/mapFolding/someAssemblyRequired/makeNuitkaSource.py +0 -0
- {mapfolding-0.2.5 → mapfolding-0.2.6}/mapFolding.egg-info/SOURCES.txt +0 -0
- {mapfolding-0.2.5 → mapfolding-0.2.6}/mapFolding.egg-info/dependency_links.txt +0 -0
- {mapfolding-0.2.5 → mapfolding-0.2.6}/mapFolding.egg-info/entry_points.txt +0 -0
- {mapfolding-0.2.5 → mapfolding-0.2.6}/mapFolding.egg-info/requires.txt +0 -0
- {mapfolding-0.2.5 → mapfolding-0.2.6}/mapFolding.egg-info/top_level.txt +0 -0
- {mapfolding-0.2.5 → mapfolding-0.2.6}/setup.cfg +0 -0
- {mapfolding-0.2.5 → mapfolding-0.2.6}/tests/__init__.py +0 -0
- {mapfolding-0.2.5 → mapfolding-0.2.6}/tests/pythons_idiotic_namespace.py +0 -0
- {mapfolding-0.2.5 → mapfolding-0.2.6}/tests/test_oeis.py +0 -0
- {mapfolding-0.2.5 → mapfolding-0.2.6}/tests/test_tasks.py +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from mapFolding.importSelector import countSequential, countParallel, countInitialize
|
|
2
|
-
from mapFolding import
|
|
2
|
+
from mapFolding import indexMy
|
|
3
3
|
from numpy import integer
|
|
4
4
|
from numpy.typing import NDArray
|
|
5
5
|
from typing import Any, Tuple
|
|
@@ -7,7 +7,7 @@ import numba
|
|
|
7
7
|
import numpy
|
|
8
8
|
|
|
9
9
|
@numba.jit(cache=True)
|
|
10
|
-
def _countFolds(connectionGraph: NDArray[integer[Any]],
|
|
10
|
+
def _countFolds(connectionGraph: NDArray[integer[Any]], foldGroups: NDArray[integer[Any]], gapsWhere: NDArray[integer[Any]], mapShape: Tuple[int, ...], my: NDArray[integer[Any]], track: NDArray[integer[Any]]):
|
|
11
11
|
"""
|
|
12
12
|
What in tarnation is this stupid module and function?
|
|
13
13
|
|
|
@@ -27,9 +27,9 @@ def _countFolds(connectionGraph: NDArray[integer[Any]], foldsSubTotals: NDArray[
|
|
|
27
27
|
|
|
28
28
|
"""
|
|
29
29
|
# print("babbage")
|
|
30
|
-
countInitialize(connectionGraph=connectionGraph, gapsWhere=gapsWhere, my=my,
|
|
30
|
+
countInitialize(connectionGraph=connectionGraph, gapsWhere=gapsWhere, my=my, track=track)
|
|
31
31
|
|
|
32
|
-
if
|
|
33
|
-
countParallel(connectionGraph=connectionGraph,
|
|
32
|
+
if my[indexMy.taskDivisions.value] > 0:
|
|
33
|
+
countParallel(connectionGraph=connectionGraph, foldGroups=foldGroups, gapsWherePARALLEL=gapsWhere, myPARALLEL=my, trackPARALLEL=track)
|
|
34
34
|
else:
|
|
35
|
-
countSequential(connectionGraph=connectionGraph,
|
|
35
|
+
countSequential(connectionGraph=connectionGraph, foldGroups=foldGroups, gapsWhere=gapsWhere, my=my, track=track)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""A relatively stable API for oft-needed functionality."""
|
|
2
|
-
from mapFolding import dtypeDefault, dtypeLarge, pathJobDEFAULT
|
|
3
|
-
from mapFolding import indexMy,
|
|
2
|
+
from mapFolding import dtypeDefault, dtypeLarge, dtypeSmall, pathJobDEFAULT
|
|
3
|
+
from mapFolding import indexMy, indexTrack, computationState
|
|
4
4
|
from mapFolding import intInnit, defineConcurrencyLimit, oopsieKwargsie
|
|
5
5
|
from numpy import integer
|
|
6
6
|
from numpy.typing import NDArray
|
|
@@ -12,7 +12,7 @@ import pathlib
|
|
|
12
12
|
import sys
|
|
13
13
|
|
|
14
14
|
def getFilenameFoldsTotal(listDimensions: Sequence[int]) -> str:
|
|
15
|
-
return str(sorted(listDimensions)).replace(', ', 'x') + '.foldsTotal'
|
|
15
|
+
return str(sorted(listDimensions)).replace(', ', 'x').replace('[', 'p').replace(']', '') + '.foldsTotal'
|
|
16
16
|
|
|
17
17
|
def getLeavesTotal(listDimensions: Sequence[int]) -> int:
|
|
18
18
|
"""
|
|
@@ -101,10 +101,11 @@ def makeConnectionGraph(listDimensions: Sequence[int], **keywordArguments: Optio
|
|
|
101
101
|
Constructs a multi-dimensional connection graph representing the connections between the leaves of a map with the given dimensions.
|
|
102
102
|
Also called a Cartesian product decomposition or dimensional product mapping.
|
|
103
103
|
|
|
104
|
-
Parameters
|
|
104
|
+
Parameters
|
|
105
105
|
listDimensions: A sequence of integers representing the dimensions of the map.
|
|
106
|
-
|
|
107
|
-
|
|
106
|
+
|
|
107
|
+
Returns
|
|
108
|
+
connectionGraph: A 3D numpy array with shape of (dimensionsTotal, leavesTotal + 1, leavesTotal + 1).
|
|
108
109
|
"""
|
|
109
110
|
datatype = keywordArguments.get('datatype', dtypeDefault)
|
|
110
111
|
mapShape = validateListDimensions(listDimensions)
|
|
@@ -116,39 +117,37 @@ def makeConnectionGraph(listDimensions: Sequence[int], **keywordArguments: Optio
|
|
|
116
117
|
cumulativeProduct = numpy.multiply.accumulate([1] + mapShape, dtype=datatype)
|
|
117
118
|
|
|
118
119
|
# Step 2: create a coordinate system
|
|
119
|
-
coordinateSystem = numpy.zeros((dimensionsTotal
|
|
120
|
+
coordinateSystem = numpy.zeros((dimensionsTotal, leavesTotal + 1), dtype=datatype)
|
|
120
121
|
|
|
121
|
-
for
|
|
122
|
+
for indexDimension in range(dimensionsTotal):
|
|
122
123
|
for leaf1ndex in range(1, leavesTotal + 1):
|
|
123
|
-
coordinateSystem[
|
|
124
|
-
((leaf1ndex - 1) // cumulativeProduct[
|
|
125
|
-
arrayDimensions[
|
|
124
|
+
coordinateSystem[indexDimension, leaf1ndex] = (
|
|
125
|
+
((leaf1ndex - 1) // cumulativeProduct[indexDimension]) %
|
|
126
|
+
arrayDimensions[indexDimension] + 1
|
|
126
127
|
)
|
|
127
128
|
|
|
128
129
|
# Step 3: create and fill the connection graph
|
|
129
|
-
connectionGraph = numpy.zeros((dimensionsTotal
|
|
130
|
+
connectionGraph = numpy.zeros((dimensionsTotal, leavesTotal + 1, leavesTotal + 1), dtype=datatype)
|
|
130
131
|
|
|
131
|
-
for
|
|
132
|
+
for indexDimension in range(dimensionsTotal):
|
|
132
133
|
for activeLeaf1ndex in range(1, leavesTotal + 1):
|
|
133
134
|
for connectee1ndex in range(1, activeLeaf1ndex + 1):
|
|
134
135
|
# Base coordinate conditions
|
|
135
|
-
isFirstCoord = coordinateSystem[
|
|
136
|
-
isLastCoord = coordinateSystem[
|
|
137
|
-
exceedsActive = connectee1ndex + cumulativeProduct[
|
|
136
|
+
isFirstCoord = coordinateSystem[indexDimension, connectee1ndex] == 1
|
|
137
|
+
isLastCoord = coordinateSystem[indexDimension, connectee1ndex] == arrayDimensions[indexDimension]
|
|
138
|
+
exceedsActive = connectee1ndex + cumulativeProduct[indexDimension] > activeLeaf1ndex
|
|
138
139
|
|
|
139
140
|
# Parity check
|
|
140
|
-
isEvenParity = (coordinateSystem[
|
|
141
|
-
(coordinateSystem[
|
|
141
|
+
isEvenParity = (coordinateSystem[indexDimension, activeLeaf1ndex] & 1) == \
|
|
142
|
+
(coordinateSystem[indexDimension, connectee1ndex] & 1)
|
|
142
143
|
|
|
143
144
|
# Determine connection value
|
|
144
145
|
if (isEvenParity and isFirstCoord) or (not isEvenParity and (isLastCoord or exceedsActive)):
|
|
145
|
-
connectionGraph[
|
|
146
|
+
connectionGraph[indexDimension, activeLeaf1ndex, connectee1ndex] = connectee1ndex
|
|
146
147
|
elif isEvenParity and not isFirstCoord:
|
|
147
|
-
connectionGraph[
|
|
148
|
+
connectionGraph[indexDimension, activeLeaf1ndex, connectee1ndex] = connectee1ndex - cumulativeProduct[indexDimension]
|
|
148
149
|
elif not isEvenParity and not (isLastCoord or exceedsActive):
|
|
149
|
-
connectionGraph[
|
|
150
|
-
else:
|
|
151
|
-
connectionGraph[dimension1ndex, activeLeaf1ndex, connectee1ndex] = connectee1ndex
|
|
150
|
+
connectionGraph[indexDimension, activeLeaf1ndex, connectee1ndex] = connectee1ndex + cumulativeProduct[indexDimension]
|
|
152
151
|
|
|
153
152
|
return connectionGraph
|
|
154
153
|
|
|
@@ -197,36 +196,38 @@ def outfitCountFolds(listDimensions: Sequence[int], computationDivisions: Option
|
|
|
197
196
|
"""
|
|
198
197
|
datatypeDefault = keywordArguments.get('datatypeDefault', dtypeDefault)
|
|
199
198
|
datatypeLarge = keywordArguments.get('datatypeLarge', dtypeLarge)
|
|
199
|
+
datatypeSmall = keywordArguments.get('datatypeSmall', dtypeSmall)
|
|
200
200
|
|
|
201
|
-
|
|
201
|
+
my = makeDataContainer(len(indexMy), datatypeDefault)
|
|
202
202
|
|
|
203
203
|
mapShape = tuple(sorted(validateListDimensions(listDimensions)))
|
|
204
|
-
the[indexThe.leavesTotal] = getLeavesTotal(mapShape)
|
|
205
|
-
the[indexThe.dimensionsTotal] = len(mapShape)
|
|
206
204
|
concurrencyLimit = setCPUlimit(CPUlimit)
|
|
207
|
-
|
|
205
|
+
my[indexMy.taskDivisions] = getTaskDivisions(computationDivisions, concurrencyLimit, CPUlimit, mapShape)
|
|
206
|
+
|
|
207
|
+
foldGroups = makeDataContainer(max(my[indexMy.taskDivisions] + 1, 2), datatypeLarge)
|
|
208
|
+
foldGroups[-1] = leavesTotal = getLeavesTotal(mapShape)
|
|
208
209
|
|
|
210
|
+
my[indexMy.dimensionsTotal] = len(mapShape)
|
|
211
|
+
my[indexMy.leaf1ndex] = 1
|
|
209
212
|
stateInitialized = computationState(
|
|
210
|
-
connectionGraph = makeConnectionGraph(mapShape, datatype=
|
|
211
|
-
|
|
213
|
+
connectionGraph = makeConnectionGraph(mapShape, datatype=datatypeSmall),
|
|
214
|
+
foldGroups = foldGroups,
|
|
212
215
|
mapShape = mapShape,
|
|
213
|
-
my =
|
|
214
|
-
gapsWhere = makeDataContainer(int(
|
|
215
|
-
|
|
216
|
-
track = makeDataContainer((len(indexTrack), the[indexThe.leavesTotal] + 1), datatypeLarge)
|
|
216
|
+
my = my,
|
|
217
|
+
gapsWhere = makeDataContainer(int(leavesTotal) * int(leavesTotal) + 1, datatypeSmall),
|
|
218
|
+
track = makeDataContainer((len(indexTrack), leavesTotal + 1), datatypeDefault)
|
|
217
219
|
)
|
|
218
220
|
|
|
219
|
-
stateInitialized['my'][indexMy.leaf1ndex.value] = 1
|
|
220
221
|
|
|
221
222
|
return stateInitialized
|
|
222
223
|
|
|
223
|
-
def parseDimensions(dimensions: Sequence[int], parameterName: str = '
|
|
224
|
+
def parseDimensions(dimensions: Sequence[int], parameterName: str = 'listDimensions') -> List[int]:
|
|
224
225
|
"""
|
|
225
226
|
Parse and validate dimensions are non-negative integers.
|
|
226
227
|
|
|
227
228
|
Parameters:
|
|
228
229
|
dimensions: Sequence of integers representing dimensions
|
|
229
|
-
parameterName ('
|
|
230
|
+
parameterName ('listDimensions'): Name of the parameter for error messages. Defaults to 'listDimensions'
|
|
230
231
|
Returns:
|
|
231
232
|
listNonNegative: List of validated non-negative integers
|
|
232
233
|
Raises:
|
|
@@ -242,10 +243,6 @@ def parseDimensions(dimensions: Sequence[int], parameterName: str = 'unnamed par
|
|
|
242
243
|
|
|
243
244
|
return listNonNegative
|
|
244
245
|
|
|
245
|
-
import tempfile
|
|
246
|
-
import shutil
|
|
247
|
-
import logging
|
|
248
|
-
import os
|
|
249
246
|
def saveFoldsTotal(pathFilename: Union[str, os.PathLike[str]], foldsTotal: int) -> None:
|
|
250
247
|
"""
|
|
251
248
|
Save foldsTotal with multiple fallback mechanisms.
|
|
@@ -254,10 +251,6 @@ def saveFoldsTotal(pathFilename: Union[str, os.PathLike[str]], foldsTotal: int)
|
|
|
254
251
|
pathFilename: Target save location
|
|
255
252
|
foldsTotal: Critical computed value to save
|
|
256
253
|
"""
|
|
257
|
-
"""Thoughts
|
|
258
|
-
Everything in a try block
|
|
259
|
-
Save it multiple times with multiple packages
|
|
260
|
-
no need for context managers, especially because they can cause errors"""
|
|
261
254
|
try:
|
|
262
255
|
pathFilenameFoldsTotal = pathlib.Path(pathFilename)
|
|
263
256
|
pathFilenameFoldsTotal.parent.mkdir(parents=True, exist_ok=True)
|
|
@@ -269,9 +262,10 @@ def saveFoldsTotal(pathFilename: Union[str, os.PathLike[str]], foldsTotal: int)
|
|
|
269
262
|
print(f"\nfoldsTotal foldsTotal foldsTotal foldsTotal foldsTotal\n\n{foldsTotal=}\n\nfoldsTotal foldsTotal foldsTotal foldsTotal foldsTotal\n")
|
|
270
263
|
randomnessPlanB = (int(str(foldsTotal).strip()[-1]) + 1) * ['YO_']
|
|
271
264
|
filenameInfixUnique = ''.join(randomnessPlanB)
|
|
272
|
-
import os
|
|
273
265
|
pathFilenamePlanB = os.path.join(os.getcwd(), 'foldsTotal' + filenameInfixUnique + '.txt')
|
|
274
|
-
open(pathFilenamePlanB, 'w')
|
|
266
|
+
writeStreamFallback = open(pathFilenamePlanB, 'w')
|
|
267
|
+
writeStreamFallback.write(str(foldsTotal))
|
|
268
|
+
writeStreamFallback.close()
|
|
275
269
|
print(str(pathFilenamePlanB))
|
|
276
270
|
except:
|
|
277
271
|
print(foldsTotal)
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
from mapFolding.lovelace import countSequential
|
|
2
|
+
from mapFolding.lovelace import countParallel
|
|
3
|
+
from mapFolding.lovelace import countInitialize
|
|
4
|
+
|
|
5
|
+
# from mapFolding.someAssemblyRequired.countSequential import countSequential
|
|
6
|
+
# from mapFolding.someAssemblyRequired.countParallel import countParallel
|
|
7
|
+
# from mapFolding.someAssemblyRequired.countInitialize import countInitialize
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from mapFolding import indexMy,
|
|
1
|
+
from mapFolding import indexMy, indexTrack
|
|
2
2
|
import numba
|
|
3
3
|
|
|
4
4
|
@numba.jit((numba.int64[::1],), parallel=False, boundscheck=False, error_model='numpy', fastmath=True, looplift=False, nogil=True, nopython=True)
|
|
@@ -10,16 +10,16 @@ def activeLeafGreaterThan0Condition(my):
|
|
|
10
10
|
return my[indexMy.leaf1ndex.value] > 0
|
|
11
11
|
|
|
12
12
|
@numba.jit((numba.int64[::1],numba.int64[::1]), parallel=False, boundscheck=False, error_model='numpy', fastmath=True, looplift=False, nogil=True, nopython=True)
|
|
13
|
-
def activeLeafGreaterThanLeavesTotalCondition(
|
|
14
|
-
return my[indexMy.leaf1ndex.value] >
|
|
13
|
+
def activeLeafGreaterThanLeavesTotalCondition(foldGroups, my):
|
|
14
|
+
return my[indexMy.leaf1ndex.value] > foldGroups[-1] # leavesTotal
|
|
15
15
|
|
|
16
16
|
@numba.jit((numba.int64[::1],), parallel=False, boundscheck=False, error_model='numpy', fastmath=True, looplift=False, nogil=True, nopython=True)
|
|
17
17
|
def activeLeafIsTheFirstLeafCondition(my):
|
|
18
18
|
return my[indexMy.leaf1ndex.value] <= 1
|
|
19
19
|
|
|
20
20
|
@numba.jit((numba.int64[::1],numba.int64[::1]), parallel=False, boundscheck=False, error_model='numpy', fastmath=True, looplift=False, nogil=True, nopython=True)
|
|
21
|
-
def allDimensionsAreUnconstrained(my
|
|
22
|
-
return my[indexMy.dimensionsUnconstrained.value] ==
|
|
21
|
+
def allDimensionsAreUnconstrained(my):
|
|
22
|
+
return my[indexMy.dimensionsUnconstrained.value] == my[indexMy.dimensionsTotal.value]
|
|
23
23
|
|
|
24
24
|
@numba.jit((numba.int64[::1],numba.int64[:,::1]), parallel=False, boundscheck=False, error_model='numpy', fastmath=True, looplift=False, nogil=True, nopython=True)
|
|
25
25
|
def backtrack(my, track):
|
|
@@ -44,20 +44,20 @@ def countGaps(gapsWhere, my, track):
|
|
|
44
44
|
|
|
45
45
|
@numba.jit((numba.int64[::1],), parallel=False, boundscheck=False, error_model='numpy', fastmath=True, looplift=False, nogil=True, nopython=True)
|
|
46
46
|
def dimension1ndexIncrement(my):
|
|
47
|
-
my[indexMy.
|
|
47
|
+
my[indexMy.indexDimension.value] += 1
|
|
48
48
|
|
|
49
49
|
@numba.jit((numba.int64[:,:,::1], numba.int64[::1]), parallel=False, boundscheck=False, error_model='numpy', fastmath=True, looplift=False, nogil=True, nopython=True)
|
|
50
50
|
def dimensionsUnconstrainedCondition(connectionGraph, my):
|
|
51
|
-
return connectionGraph[my[indexMy.
|
|
51
|
+
return connectionGraph[my[indexMy.indexDimension.value], my[indexMy.leaf1ndex.value], my[indexMy.leaf1ndex.value]] == my[indexMy.leaf1ndex.value]
|
|
52
52
|
|
|
53
53
|
@numba.jit((numba.int64[::1],), parallel=False, boundscheck=False, error_model='numpy', fastmath=True, looplift=False, nogil=True, nopython=True)
|
|
54
54
|
def dimensionsUnconstrainedIncrement(my):
|
|
55
55
|
my[indexMy.dimensionsUnconstrained.value] += 1
|
|
56
56
|
|
|
57
57
|
@numba.jit((numba.int64[::1],numba.int64[::1],numba.int64[::1],numba.int64[:,::1]), parallel=False, boundscheck=False, error_model='numpy', fastmath=True, looplift=False, nogil=True, nopython=True)
|
|
58
|
-
def filterCommonGaps(gapsWhere, my,
|
|
58
|
+
def filterCommonGaps(gapsWhere, my, track):
|
|
59
59
|
gapsWhere[my[indexMy.gap1ndex.value]] = gapsWhere[my[indexMy.indexMiniGap.value]]
|
|
60
|
-
if track[indexTrack.countDimensionsGapped.value, gapsWhere[my[indexMy.indexMiniGap.value]]] ==
|
|
60
|
+
if track[indexTrack.countDimensionsGapped.value, gapsWhere[my[indexMy.indexMiniGap.value]]] == my[indexMy.dimensionsTotal.value] - my[indexMy.dimensionsUnconstrained.value]:
|
|
61
61
|
activeGapIncrement(my=my)
|
|
62
62
|
track[indexTrack.countDimensionsGapped.value, gapsWhere[my[indexMy.indexMiniGap.value]]] = 0
|
|
63
63
|
|
|
@@ -65,11 +65,11 @@ def filterCommonGaps(gapsWhere, my, the, track):
|
|
|
65
65
|
def findGapsInitializeVariables(my, track):
|
|
66
66
|
my[indexMy.dimensionsUnconstrained.value] = 0
|
|
67
67
|
my[indexMy.gap1ndexCeiling.value] = track[indexTrack.gapRangeStart.value, my[indexMy.leaf1ndex.value] - 1]
|
|
68
|
-
my[indexMy.
|
|
68
|
+
my[indexMy.indexDimension.value] = 0
|
|
69
69
|
|
|
70
70
|
@numba.jit((numba.int64[::1],numba.int64[::1],numba.int64[::1]), parallel=False, boundscheck=False, error_model='numpy', fastmath=True, looplift=False, nogil=True, nopython=True)
|
|
71
|
-
def foldsSubTotalIncrement(
|
|
72
|
-
|
|
71
|
+
def foldsSubTotalIncrement(foldGroups, my):
|
|
72
|
+
foldGroups[my[indexMy.taskIndex.value]] += 1
|
|
73
73
|
|
|
74
74
|
@numba.jit((numba.int64[::1],), parallel=False, boundscheck=False, error_model='numpy', fastmath=True, looplift=False, nogil=True, nopython=True)
|
|
75
75
|
def indexMiniGapIncrement(my):
|
|
@@ -93,19 +93,19 @@ def leafBelowSentinelIs1Condition(track):
|
|
|
93
93
|
|
|
94
94
|
@numba.jit((numba.int64[:,:,::1], numba.int64[::1]), parallel=False, boundscheck=False, error_model='numpy', fastmath=True, looplift=False, nogil=True, nopython=True)
|
|
95
95
|
def leafConnecteeInitialization(connectionGraph, my):
|
|
96
|
-
my[indexMy.leafConnectee.value] = connectionGraph[my[indexMy.
|
|
96
|
+
my[indexMy.leafConnectee.value] = connectionGraph[my[indexMy.indexDimension.value], my[indexMy.leaf1ndex.value], my[indexMy.leaf1ndex.value]]
|
|
97
97
|
|
|
98
98
|
@numba.jit((numba.int64[:,:,::1], numba.int64[::1],numba.int64[:,::1]), parallel=False, boundscheck=False, error_model='numpy', fastmath=True, looplift=False, nogil=True, nopython=True)
|
|
99
99
|
def leafConnecteeUpdate(connectionGraph, my, track):
|
|
100
|
-
my[indexMy.leafConnectee.value] = connectionGraph[my[indexMy.
|
|
100
|
+
my[indexMy.leafConnectee.value] = connectionGraph[my[indexMy.indexDimension.value], my[indexMy.leaf1ndex.value], track[indexTrack.leafBelow.value, my[indexMy.leafConnectee.value]]]
|
|
101
101
|
|
|
102
102
|
@numba.jit((numba.int64[::1],), parallel=False, boundscheck=False, error_model='numpy', fastmath=True, looplift=False, nogil=True, nopython=True)
|
|
103
103
|
def loopingLeavesConnectedToActiveLeaf(my):
|
|
104
104
|
return my[indexMy.leafConnectee.value] != my[indexMy.leaf1ndex.value]
|
|
105
105
|
|
|
106
106
|
@numba.jit((numba.int64[::1],numba.int64[::1]), parallel=False, boundscheck=False, error_model='numpy', fastmath=True, looplift=False, nogil=True, nopython=True)
|
|
107
|
-
def loopingTheDimensions(my
|
|
108
|
-
return my[indexMy.
|
|
107
|
+
def loopingTheDimensions(my):
|
|
108
|
+
return my[indexMy.indexDimension.value] < my[indexMy.dimensionsTotal.value]
|
|
109
109
|
|
|
110
110
|
@numba.jit((numba.int64[::1],), parallel=False, boundscheck=False, error_model='numpy', fastmath=True, looplift=False, nogil=True, nopython=True)
|
|
111
111
|
def loopingToActiveGapCeiling(my):
|
|
@@ -126,15 +126,15 @@ def placeLeafCondition(my):
|
|
|
126
126
|
return my[indexMy.leaf1ndex.value] > 0
|
|
127
127
|
|
|
128
128
|
@numba.jit((numba.int64[::1],numba.int64[::1]), parallel=False, boundscheck=False, error_model='numpy', fastmath=True, looplift=False, nogil=True, nopython=True)
|
|
129
|
-
def thereAreComputationDivisionsYouMightSkip(my
|
|
130
|
-
return my[indexMy.leaf1ndex.value] !=
|
|
129
|
+
def thereAreComputationDivisionsYouMightSkip(my):
|
|
130
|
+
return my[indexMy.leaf1ndex.value] != my[indexMy.taskDivisions.value] or my[indexMy.leafConnectee.value] % my[indexMy.taskDivisions.value] == my[indexMy.taskIndex.value]
|
|
131
131
|
|
|
132
|
-
@numba.jit((numba.int64[:,:,::1], numba.int64[::1], numba.int64[::1], numba.int64[
|
|
133
|
-
def countInitialize(connectionGraph, gapsWhere, my,
|
|
132
|
+
@numba.jit((numba.int64[:,:,::1], numba.int64[::1], numba.int64[::1], numba.int64[:,::1]), parallel=False, boundscheck=False, error_model='numpy', fastmath=True, looplift=False, nogil=True, nopython=True)
|
|
133
|
+
def countInitialize(connectionGraph, gapsWhere, my, track):
|
|
134
134
|
while activeLeafGreaterThan0Condition(my=my):
|
|
135
135
|
if activeLeafIsTheFirstLeafCondition(my=my) or leafBelowSentinelIs1Condition(track=track):
|
|
136
136
|
findGapsInitializeVariables(my=my, track=track)
|
|
137
|
-
while loopingTheDimensions(my=my
|
|
137
|
+
while loopingTheDimensions(my=my):
|
|
138
138
|
if dimensionsUnconstrainedCondition(connectionGraph=connectionGraph, my=my):
|
|
139
139
|
dimensionsUnconstrainedIncrement(my=my)
|
|
140
140
|
else:
|
|
@@ -143,26 +143,26 @@ def countInitialize(connectionGraph, gapsWhere, my, the, track):
|
|
|
143
143
|
countGaps(gapsWhere=gapsWhere, my=my, track=track)
|
|
144
144
|
leafConnecteeUpdate(connectionGraph=connectionGraph, my=my, track=track)
|
|
145
145
|
dimension1ndexIncrement(my=my)
|
|
146
|
-
if allDimensionsAreUnconstrained(my=my
|
|
146
|
+
if allDimensionsAreUnconstrained(my=my):
|
|
147
147
|
insertUnconstrainedLeaf(gapsWhere=gapsWhere, my=my)
|
|
148
148
|
indexMiniGapInitialization(my=my)
|
|
149
149
|
while loopingToActiveGapCeiling(my=my):
|
|
150
|
-
filterCommonGaps(gapsWhere=gapsWhere, my=my,
|
|
150
|
+
filterCommonGaps(gapsWhere=gapsWhere, my=my, track=track)
|
|
151
151
|
indexMiniGapIncrement(my=my)
|
|
152
152
|
if placeLeafCondition(my=my):
|
|
153
153
|
placeLeaf(gapsWhere=gapsWhere, my=my, track=track)
|
|
154
154
|
if my[indexMy.gap1ndex.value] > 0:
|
|
155
155
|
return
|
|
156
156
|
|
|
157
|
-
@numba.jit((numba.int64[:,:,::1], numba.int64[::1], numba.int64[::1], numba.int64[::1], numba.int64[
|
|
158
|
-
def countSequential(connectionGraph,
|
|
157
|
+
@numba.jit((numba.int64[:,:,::1], numba.int64[::1], numba.int64[::1], numba.int64[::1], numba.int64[:,::1]), parallel=False, boundscheck=False, error_model='numpy', fastmath=True, looplift=False, nogil=True, nopython=True)
|
|
158
|
+
def countSequential(connectionGraph, foldGroups, gapsWhere, my, track):
|
|
159
159
|
while activeLeafGreaterThan0Condition(my=my):
|
|
160
160
|
if activeLeafIsTheFirstLeafCondition(my=my) or leafBelowSentinelIs1Condition(track=track):
|
|
161
|
-
if activeLeafGreaterThanLeavesTotalCondition(
|
|
162
|
-
foldsSubTotalIncrement(
|
|
161
|
+
if activeLeafGreaterThanLeavesTotalCondition(foldGroups=foldGroups, my=my):
|
|
162
|
+
foldsSubTotalIncrement(foldGroups=foldGroups, my=my)
|
|
163
163
|
else:
|
|
164
164
|
findGapsInitializeVariables(my=my, track=track)
|
|
165
|
-
while loopingTheDimensions(my=my
|
|
165
|
+
while loopingTheDimensions(my=my):
|
|
166
166
|
if dimensionsUnconstrainedCondition(connectionGraph=connectionGraph, my=my):
|
|
167
167
|
dimensionsUnconstrainedIncrement(my=my)
|
|
168
168
|
else:
|
|
@@ -173,39 +173,39 @@ def countSequential(connectionGraph, foldsSubTotals, gapsWhere, my, the, track):
|
|
|
173
173
|
dimension1ndexIncrement(my=my)
|
|
174
174
|
indexMiniGapInitialization(my=my)
|
|
175
175
|
while loopingToActiveGapCeiling(my=my):
|
|
176
|
-
filterCommonGaps(gapsWhere=gapsWhere, my=my,
|
|
176
|
+
filterCommonGaps(gapsWhere=gapsWhere, my=my, track=track)
|
|
177
177
|
indexMiniGapIncrement(my=my)
|
|
178
178
|
while backtrackCondition(my=my, track=track):
|
|
179
179
|
backtrack(my=my, track=track)
|
|
180
180
|
if placeLeafCondition(my=my):
|
|
181
181
|
placeLeaf(gapsWhere=gapsWhere, my=my, track=track)
|
|
182
182
|
|
|
183
|
-
@numba.jit((numba.int64[:,:,::1], numba.int64[::1], numba.int64[::1],numba.int64[::1],numba.int64[
|
|
184
|
-
def countParallel(connectionGraph,
|
|
185
|
-
for indexSherpa in numba.prange(
|
|
183
|
+
@numba.jit((numba.int64[:,:,::1], numba.int64[::1], numba.int64[::1], numba.int64[::1], numba.int64[:,::1]), parallel=True, boundscheck=False, error_model='numpy', fastmath=True, looplift=False, nogil=True, nopython=True)
|
|
184
|
+
def countParallel(connectionGraph, foldGroups, gapsWherePARALLEL, myPARALLEL, trackPARALLEL):
|
|
185
|
+
for indexSherpa in numba.prange(myPARALLEL[indexMy.taskDivisions.value]):
|
|
186
186
|
gapsWhere = gapsWherePARALLEL.copy()
|
|
187
187
|
my = myPARALLEL.copy()
|
|
188
188
|
my[indexMy.taskIndex.value] = indexSherpa
|
|
189
189
|
track = trackPARALLEL.copy()
|
|
190
190
|
while activeLeafGreaterThan0Condition(my=my):
|
|
191
191
|
if activeLeafIsTheFirstLeafCondition(my=my) or leafBelowSentinelIs1Condition(track=track):
|
|
192
|
-
if activeLeafGreaterThanLeavesTotalCondition(
|
|
193
|
-
foldsSubTotalIncrement(
|
|
192
|
+
if activeLeafGreaterThanLeavesTotalCondition(foldGroups=foldGroups, my=my):
|
|
193
|
+
foldsSubTotalIncrement(foldGroups=foldGroups, my=my)
|
|
194
194
|
else:
|
|
195
195
|
findGapsInitializeVariables(my=my, track=track)
|
|
196
|
-
while loopingTheDimensions(my=my
|
|
196
|
+
while loopingTheDimensions(my=my):
|
|
197
197
|
if dimensionsUnconstrainedCondition(connectionGraph=connectionGraph, my=my):
|
|
198
198
|
dimensionsUnconstrainedIncrement(my=my)
|
|
199
199
|
else:
|
|
200
200
|
leafConnecteeInitialization(connectionGraph=connectionGraph, my=my)
|
|
201
201
|
while loopingLeavesConnectedToActiveLeaf(my=my):
|
|
202
|
-
if thereAreComputationDivisionsYouMightSkip(my=my
|
|
202
|
+
if thereAreComputationDivisionsYouMightSkip(my=my):
|
|
203
203
|
countGaps(gapsWhere=gapsWhere, my=my, track=track)
|
|
204
204
|
leafConnecteeUpdate(connectionGraph=connectionGraph, my=my, track=track)
|
|
205
205
|
dimension1ndexIncrement(my=my)
|
|
206
206
|
indexMiniGapInitialization(my=my)
|
|
207
207
|
while loopingToActiveGapCeiling(my=my):
|
|
208
|
-
filterCommonGaps(gapsWhere=gapsWhere, my=my,
|
|
208
|
+
filterCommonGaps(gapsWhere=gapsWhere, my=my, track=track)
|
|
209
209
|
indexMiniGapIncrement(my=my)
|
|
210
210
|
while backtrackCondition(my=my, track=track):
|
|
211
211
|
backtrack(my=my, track=track)
|
|
@@ -125,7 +125,7 @@ def Z0Z_inlineMapFolding():
|
|
|
125
125
|
|
|
126
126
|
listPathFilenamesDestination: list[pathlib.Path] = []
|
|
127
127
|
for callableTarget in listCallables:
|
|
128
|
-
pathFilenameDestination = pathFilenameSource.with_stem(callableTarget)
|
|
128
|
+
pathFilenameDestination = pathFilenameSource.parent / "someAssemblyRequired" / pathFilenameSource.with_stem(callableTarget).name
|
|
129
129
|
codeInlined = inlineFunctions(codeSource, callableTarget, dictionaryEnumValues)
|
|
130
130
|
pathFilenameDestination.write_text(codeInlined)
|
|
131
131
|
listPathFilenamesDestination.append(pathFilenameDestination)
|
|
@@ -3,7 +3,7 @@ from typing import Any, Optional, Sequence, Type, Union
|
|
|
3
3
|
def Z0Z_makeJob(listDimensions: Sequence[int], **keywordArguments: Optional[Type[Any]]):
|
|
4
4
|
from mapFolding import outfitCountFolds
|
|
5
5
|
stateUniversal = outfitCountFolds(listDimensions, computationDivisions=None, CPUlimit=None, **keywordArguments)
|
|
6
|
-
from mapFolding.
|
|
6
|
+
from mapFolding.someAssemblyRequired.countInitializeNoNumba import countInitialize
|
|
7
7
|
countInitialize(stateUniversal['connectionGraph'], stateUniversal['gapsWhere'], stateUniversal['my'], stateUniversal['the'], stateUniversal['track'])
|
|
8
8
|
from mapFolding import getPathFilenameFoldsTotal
|
|
9
9
|
pathFilenameChopChop = getPathFilenameFoldsTotal(stateUniversal['mapShape'])
|
|
@@ -38,7 +38,7 @@ def runJob(pathFilename):
|
|
|
38
38
|
the: Final[numpy.ndarray] = stateJob['the']
|
|
39
39
|
track: numpy.ndarray = stateJob['track']
|
|
40
40
|
|
|
41
|
-
from mapFolding.countSequentialNoNumba import countSequential
|
|
41
|
+
from mapFolding.someAssemblyRequired.countSequentialNoNumba import countSequential
|
|
42
42
|
countSequential(connectionGraph, foldsSubTotals, gapsWhere, my, the, track)
|
|
43
43
|
|
|
44
44
|
print(foldsSubTotals.sum().item())
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
"""Create a python module hardcoded to compute a map's foldsTotal.
|
|
2
|
-
NumPy ndarray.
|
|
3
|
-
Numba optimized.
|
|
4
|
-
Absolutely no other imports.
|
|
2
|
+
- NumPy ndarray.
|
|
3
|
+
- Numba optimized.
|
|
4
|
+
- Absolutely no other imports.
|
|
5
|
+
|
|
6
|
+
Can create LLVM IR from the module: of unknown utility.
|
|
5
7
|
"""
|
|
6
|
-
from mapFolding import
|
|
8
|
+
# from mapFolding import dtypeDefault, dtypeSmall
|
|
9
|
+
from mapFolding import make_dtype, datatypeLarge, dtypeLarge
|
|
7
10
|
from mapFolding.someAssemblyRequired.inlineAfunction import Z0Z_inlineMapFolding
|
|
8
11
|
from mapFolding.someAssemblyRequired.jobsAndTasks import Z0Z_makeJob
|
|
9
12
|
import importlib
|
|
@@ -11,30 +14,50 @@ import llvmlite.binding
|
|
|
11
14
|
import numpy
|
|
12
15
|
import pathlib
|
|
13
16
|
import pickle
|
|
17
|
+
import python_minifier
|
|
14
18
|
|
|
15
|
-
listDimensions = [
|
|
19
|
+
listDimensions = [6,6]
|
|
16
20
|
|
|
17
21
|
# NOTE this overwrites files
|
|
18
22
|
Z0Z_inlineMapFolding()
|
|
19
23
|
|
|
20
24
|
identifierCallableLaunch = "goGoGadgetAbsurdity"
|
|
21
25
|
|
|
22
|
-
def
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
+
def convertNDArrayToStr(arrayTarget: numpy.ndarray, identifierName: str) -> str:
|
|
27
|
+
arrayAsTypeStr = numpy.array2string(arrayTarget, threshold=100000, max_line_width=200, separator=',')
|
|
28
|
+
stringMinimized = python_minifier.minify(arrayAsTypeStr)
|
|
29
|
+
commaZeroMaximum = arrayTarget.shape[-1] - 1
|
|
30
|
+
stringMinimized = stringMinimized.replace('[0' + ',0'*commaZeroMaximum + ']', '[0]*'+str(commaZeroMaximum+1))
|
|
31
|
+
for countZeros in range(commaZeroMaximum, 2, -1):
|
|
32
|
+
stringMinimized = stringMinimized.replace(',0'*countZeros + ']', ']+[0]*'+str(countZeros))
|
|
33
|
+
return f"{identifierName} = numpy.array({stringMinimized}, dtype=numpy.{arrayTarget.dtype})"
|
|
26
34
|
|
|
27
35
|
def writeModuleWithNumba(listDimensions):
|
|
28
36
|
numpy_dtypeLarge = dtypeLarge
|
|
29
|
-
numpy_dtypeDefault = dtypeDefault
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
# numpy_dtypeDefault = dtypeDefault
|
|
38
|
+
datatypeDefault = 'uint8'
|
|
39
|
+
numpy_dtypeDefault = make_dtype(datatypeDefault)
|
|
40
|
+
numpy_dtypeSmall = numpy_dtypeDefault
|
|
41
|
+
|
|
42
|
+
parametersNumba = f"numba.types.{datatypeLarge}(), \
|
|
43
|
+
cache=True, \
|
|
44
|
+
"
|
|
45
|
+
# no_cfunc_wrapper=True, \
|
|
46
|
+
# no_cpython_wrapper=True, \
|
|
47
|
+
# _nrt=True, \
|
|
48
|
+
# nopython=True, \
|
|
49
|
+
# parallel=False, \
|
|
50
|
+
# boundscheck=False, \
|
|
51
|
+
# error_model='numpy', \
|
|
52
|
+
# fastmath=True, \
|
|
53
|
+
# no_cfunc_wrapper=False, \
|
|
54
|
+
# no_cpython_wrapper=False, \
|
|
55
|
+
# looplift=True, \
|
|
56
|
+
# forceinline=True, \
|
|
57
|
+
|
|
58
|
+
pathFilenameData = Z0Z_makeJob(listDimensions, datatypeDefault=numpy_dtypeDefault, datatypeLarge=numpy_dtypeLarge, datatypeSmall=numpy_dtypeSmall)
|
|
59
|
+
|
|
60
|
+
pathFilenameAlgorithm = pathlib.Path('/apps/mapFolding/mapFolding/someAssemblyRequired/countSequentialNoNumba.py')
|
|
38
61
|
pathFilenameDestination = pathFilenameData.with_stem(pathFilenameData.parent.name).with_suffix(".py")
|
|
39
62
|
|
|
40
63
|
lineNumba = f"@numba.jit({parametersNumba})"
|
|
@@ -49,16 +72,17 @@ def writeModuleWithNumba(listDimensions):
|
|
|
49
72
|
ImaIndent = ' '
|
|
50
73
|
linesDataDynamic = """"""
|
|
51
74
|
linesDataDynamic = "\n".join([linesDataDynamic
|
|
52
|
-
, ImaIndent +
|
|
53
|
-
, ImaIndent +
|
|
54
|
-
, ImaIndent +
|
|
55
|
-
, ImaIndent +
|
|
75
|
+
, ImaIndent + f"foldsTotal = numba.types.{datatypeLarge}(0)"
|
|
76
|
+
, ImaIndent + convertNDArrayToStr(stateJob['my'], 'my')
|
|
77
|
+
, ImaIndent + convertNDArrayToStr(stateJob['foldsSubTotals'], 'foldsSubTotals')
|
|
78
|
+
, ImaIndent + convertNDArrayToStr(stateJob['gapsWhere'], 'gapsWhere')
|
|
79
|
+
, ImaIndent + convertNDArrayToStr(stateJob['track'], 'track')
|
|
56
80
|
])
|
|
57
81
|
|
|
58
82
|
linesDataStatic = """"""
|
|
59
83
|
linesDataStatic = "\n".join([linesDataStatic
|
|
60
|
-
, ImaIndent +
|
|
61
|
-
, ImaIndent +
|
|
84
|
+
, ImaIndent + convertNDArrayToStr(stateJob['the'], 'the')
|
|
85
|
+
, ImaIndent + convertNDArrayToStr(stateJob['connectionGraph'], 'connectionGraph')
|
|
62
86
|
])
|
|
63
87
|
|
|
64
88
|
pathFilenameFoldsTotal: pathlib.Path = stateJob['pathFilenameFoldsTotal']
|
|
@@ -79,26 +103,25 @@ def writeModuleWithNumba(listDimensions):
|
|
|
79
103
|
, lineSource
|
|
80
104
|
])
|
|
81
105
|
|
|
82
|
-
lineReturn = f"{ImaIndent}return foldsSubTotals.sum().item()"
|
|
83
|
-
|
|
84
106
|
linesLaunch = """"""
|
|
85
107
|
linesLaunch = linesLaunch + f"""
|
|
86
108
|
if __name__ == '__main__':
|
|
87
|
-
|
|
109
|
+
{identifierCallableLaunch}()"""
|
|
88
110
|
|
|
89
111
|
linesWriteFoldsTotal = """"""
|
|
90
112
|
linesWriteFoldsTotal = "\n".join([linesWriteFoldsTotal
|
|
113
|
+
, " foldsTotal = foldsSubTotals.sum().item()"
|
|
91
114
|
, " print(foldsTotal)"
|
|
92
|
-
,
|
|
115
|
+
, " with numba.objmode():"
|
|
116
|
+
, f" open('{pathFilenameFoldsTotal.as_posix()}', 'w').write(str(foldsTotal))"
|
|
117
|
+
, " return foldsTotal"
|
|
93
118
|
])
|
|
94
119
|
|
|
95
120
|
linesAll = "\n".join([
|
|
96
121
|
linesImport
|
|
97
122
|
, linesAlgorithm
|
|
98
|
-
, f"{ImaIndent}print(foldsSubTotals.sum().item())"
|
|
99
|
-
, lineReturn
|
|
100
|
-
, linesLaunch
|
|
101
123
|
, linesWriteFoldsTotal
|
|
124
|
+
, linesLaunch
|
|
102
125
|
])
|
|
103
126
|
|
|
104
127
|
pathFilenameDestination.write_text(linesAll)
|
|
@@ -42,7 +42,7 @@ def countFolds(listDimensions: Sequence[int], pathishWriteFoldsTotal: Optional[U
|
|
|
42
42
|
from mapFolding.babbage import _countFolds
|
|
43
43
|
_countFolds(**stateUniversal)
|
|
44
44
|
|
|
45
|
-
foldsTotal = stateUniversal['
|
|
45
|
+
foldsTotal = stateUniversal['foldGroups'][0:-1].sum() * stateUniversal['foldGroups'][-1]
|
|
46
46
|
|
|
47
47
|
if pathFilenameFoldsTotal is not None:
|
|
48
48
|
saveFoldsTotal(pathFilenameFoldsTotal, foldsTotal)
|
|
@@ -42,21 +42,22 @@ class EnumIndices(enum.IntEnum):
|
|
|
42
42
|
|
|
43
43
|
class indexMy(EnumIndices):
|
|
44
44
|
"""Indices for dynamic values."""
|
|
45
|
-
|
|
45
|
+
dimensionsTotal = enum.auto() # connectionGraph.shape[0]
|
|
46
46
|
dimensionsUnconstrained = enum.auto()
|
|
47
47
|
gap1ndex = enum.auto()
|
|
48
48
|
gap1ndexCeiling = enum.auto()
|
|
49
|
+
indexDimension = enum.auto()
|
|
49
50
|
indexLeaf = enum.auto()
|
|
50
51
|
indexMiniGap = enum.auto()
|
|
51
52
|
leaf1ndex = enum.auto()
|
|
52
53
|
leafConnectee = enum.auto()
|
|
54
|
+
taskDivisions = enum.auto()
|
|
53
55
|
taskIndex = enum.auto()
|
|
54
56
|
|
|
55
|
-
class indexThe(EnumIndices):
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
taskDivisions = enum.auto()
|
|
57
|
+
# class indexThe(EnumIndices):
|
|
58
|
+
# """Indices for static values."""
|
|
59
|
+
# dimensionsTotal = enum.auto() # connectionGraph.shape[0]
|
|
60
|
+
# taskDivisions = enum.auto()
|
|
60
61
|
|
|
61
62
|
class indexTrack(EnumIndices):
|
|
62
63
|
"""Indices for state tracking array."""
|
|
@@ -67,9 +68,9 @@ class indexTrack(EnumIndices):
|
|
|
67
68
|
|
|
68
69
|
class computationState(TypedDict):
|
|
69
70
|
connectionGraph: numpy.typing.NDArray[numpy.integer[Any]]
|
|
70
|
-
|
|
71
|
+
foldGroups: numpy.typing.NDArray[numpy.integer[Any]]
|
|
71
72
|
gapsWhere: numpy.typing.NDArray[numpy.integer[Any]]
|
|
72
73
|
mapShape: Tuple[int, ...]
|
|
73
74
|
my: numpy.typing.NDArray[numpy.integer[Any]]
|
|
74
|
-
the: numpy.typing.NDArray[numpy.integer[Any]]
|
|
75
|
+
# the: numpy.typing.NDArray[numpy.integer[Any]]
|
|
75
76
|
track: numpy.typing.NDArray[numpy.integer[Any]]
|
|
@@ -7,7 +7,7 @@ name = "mapFolding"
|
|
|
7
7
|
description = "Count distinct ways to fold a map (or a strip of stamps)"
|
|
8
8
|
readme = "README.md"
|
|
9
9
|
authors = [{ name = "Hunter Hogan", email = "HunterHogan@pm.me" }]
|
|
10
|
-
version = "0.2.
|
|
10
|
+
version = "0.2.6"
|
|
11
11
|
requires-python = ">=3.10,<3.13"
|
|
12
12
|
dependencies = ["numba", "numpy", "Z0Z-tools"]
|
|
13
13
|
urls = { homepage = "https://github.com/hunterhogan/mapFolding" }
|
|
@@ -42,5 +42,5 @@ output = "tests/coverage/coverage.xml"
|
|
|
42
42
|
|
|
43
43
|
[tool.pytest.ini_options]
|
|
44
44
|
testpaths = ["tests"]
|
|
45
|
-
addopts = ["--color=yes", "-n
|
|
46
|
-
|
|
45
|
+
addopts = ["--color=yes", "-n 4"]
|
|
46
|
+
env = ["NUMBA_DISABLE_JIT=1"]
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
"""SSOT for Pytest
|
|
2
|
-
Other test modules must not import directly from the package being tested."""
|
|
1
|
+
"""SSOT for Pytest"""
|
|
3
2
|
|
|
4
3
|
# TODO learn how to run tests and coverage analysis without `env = ["NUMBA_DISABLE_JIT=1"]`
|
|
5
4
|
|
|
@@ -13,7 +12,7 @@ import uuid
|
|
|
13
12
|
from Z0Z_tools.pytest_parseParameters import makeTestSuiteConcurrencyLimit
|
|
14
13
|
from Z0Z_tools.pytest_parseParameters import makeTestSuiteIntInnit
|
|
15
14
|
from Z0Z_tools.pytest_parseParameters import makeTestSuiteOopsieKwargsie
|
|
16
|
-
from mapFolding import countFolds, pathJobDEFAULT, indexMy,
|
|
15
|
+
from mapFolding import countFolds, pathJobDEFAULT, indexMy, indexTrack, saveFoldsTotal
|
|
17
16
|
from mapFolding import defineConcurrencyLimit, intInnit, oopsieKwargsie, outfitCountFolds
|
|
18
17
|
from mapFolding import oeisIDfor_n, getOEISids, clearOEIScache, getFilenameFoldsTotal
|
|
19
18
|
from mapFolding.beDRY import getLeavesTotal, parseDimensions, validateListDimensions
|
|
@@ -41,7 +40,6 @@ __all__ = [
|
|
|
41
40
|
'getLeavesTotal',
|
|
42
41
|
'getOEISids',
|
|
43
42
|
'getTaskDivisions',
|
|
44
|
-
'indexThe',
|
|
45
43
|
'intInnit',
|
|
46
44
|
'makeConnectionGraph',
|
|
47
45
|
'makeDataContainer',
|
|
@@ -53,6 +51,7 @@ __all__ = [
|
|
|
53
51
|
'oopsieKwargsie',
|
|
54
52
|
'outfitCountFolds',
|
|
55
53
|
'parseDimensions',
|
|
54
|
+
'saveFoldsTotal',
|
|
56
55
|
'setCPUlimit',
|
|
57
56
|
'settingsOEIS',
|
|
58
57
|
'standardCacheTest',
|
|
@@ -240,13 +239,12 @@ def oeisID_1random() -> str:
|
|
|
240
239
|
def mockFoldingFunction():
|
|
241
240
|
"""Creates a mock function that simulates _countFolds behavior."""
|
|
242
241
|
def make_mock(foldsValue: int, listDimensions: List[int]):
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
mock_array =
|
|
246
|
-
mock_array[arraySize - 1] = foldsValue # Put entire value in last position
|
|
242
|
+
mock_array = makeDataContainer(2)
|
|
243
|
+
mock_array[0] = foldsValue
|
|
244
|
+
mock_array[-1] = getLeavesTotal(listDimensions)
|
|
247
245
|
|
|
248
246
|
def mock_countfolds(**keywordArguments):
|
|
249
|
-
keywordArguments['
|
|
247
|
+
keywordArguments['foldGroups'][:] = mock_array
|
|
250
248
|
return None
|
|
251
249
|
|
|
252
250
|
return mock_countfolds
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import pathlib
|
|
2
2
|
from tests.conftest import *
|
|
3
3
|
from tests.pythons_idiotic_namespace import *
|
|
4
|
-
from typing import List, Optional
|
|
4
|
+
from typing import List, Optional, Any
|
|
5
5
|
import itertools
|
|
6
6
|
import numba
|
|
7
7
|
import numpy
|
|
@@ -9,6 +9,8 @@ import pytest
|
|
|
9
9
|
import random
|
|
10
10
|
import sys
|
|
11
11
|
import unittest.mock
|
|
12
|
+
import io
|
|
13
|
+
from contextlib import redirect_stdout
|
|
12
14
|
|
|
13
15
|
@pytest.mark.parametrize("listDimensions,expected_intInnit,expected_parseListDimensions,expected_validateListDimensions,expected_getLeavesTotal", [
|
|
14
16
|
(None, ValueError, ValueError, ValueError, ValueError), # None instead of list
|
|
@@ -81,13 +83,14 @@ def test_countFolds_writeFoldsTotal(
|
|
|
81
83
|
pathWriteTarget = pathTempTesting / writeFoldsTarget
|
|
82
84
|
filenameFoldsTotalExpected = writeFoldsTarget
|
|
83
85
|
|
|
86
|
+
foldsTotalExpected = foldsValue * getLeavesTotal(listDimensionsTestFunctionality)
|
|
84
87
|
mock_countFolds = mockFoldingFunction(foldsValue, listDimensionsTestFunctionality)
|
|
85
88
|
|
|
86
89
|
with unittest.mock.patch("mapFolding.babbage._countFolds", side_effect=mock_countFolds):
|
|
87
90
|
returned = countFolds(listDimensionsTestFunctionality, pathishWriteFoldsTotal=pathWriteTarget)
|
|
88
91
|
|
|
89
|
-
standardComparison(foldsValue, lambda: returned) # Check return value
|
|
90
|
-
standardComparison(str(
|
|
92
|
+
# standardComparison(foldsValue, lambda: returned) # Check return value
|
|
93
|
+
standardComparison(str(foldsTotalExpected), lambda: (pathTempTesting / filenameFoldsTotalExpected).read_text()) # Check file content
|
|
91
94
|
|
|
92
95
|
def test_intInnit() -> None:
|
|
93
96
|
"""Test integer parsing using the test suite generator."""
|
|
@@ -266,3 +269,14 @@ def test_pathJobDEFAULT_colab():
|
|
|
266
269
|
|
|
267
270
|
# Reload one more time to restore original state
|
|
268
271
|
importlib.reload(mapFolding.theSSOT)
|
|
272
|
+
|
|
273
|
+
def test_saveFoldsTotal_fallback(pathTempTesting: pathlib.Path) -> None:
|
|
274
|
+
foldsTotal = 123
|
|
275
|
+
pathFilename = pathTempTesting / "unwritable" / "foldsTotal.txt"
|
|
276
|
+
with unittest.mock.patch("pathlib.Path.write_text", side_effect=OSError("Simulated write failure")):
|
|
277
|
+
with unittest.mock.patch("os.getcwd", return_value=str(pathTempTesting)):
|
|
278
|
+
capturedOutput = io.StringIO()
|
|
279
|
+
with redirect_stdout(capturedOutput):
|
|
280
|
+
saveFoldsTotal(pathFilename, foldsTotal)
|
|
281
|
+
fallbackFiles = list(pathTempTesting.glob("foldsTotalYO_*.txt"))
|
|
282
|
+
assert len(fallbackFiles) == 1, "Fallback file was not created upon write failure."
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
from mapFolding.lovelace import countSequential
|
|
2
|
-
from mapFolding.lovelace import countParallel
|
|
3
|
-
from mapFolding.lovelace import countInitialize
|
|
4
|
-
|
|
5
|
-
# from mapFolding.countSequential import countSequential
|
|
6
|
-
# from mapFolding.countParallel import countParallel
|
|
7
|
-
# from mapFolding.countInitialize import countInitialize
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|