mapFolding 0.11.1__tar.gz → 0.11.3__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.11.1 → mapfolding-0.11.3}/PKG-INFO +16 -11
- {mapfolding-0.11.1 → mapfolding-0.11.3}/README.md +15 -7
- mapfolding-0.11.3/mapFolding/__init__.py +62 -0
- {mapfolding-0.11.1 → mapfolding-0.11.3}/mapFolding/basecamp.py +15 -13
- {mapfolding-0.11.1 → mapfolding-0.11.3}/mapFolding/beDRY.py +4 -36
- {mapfolding-0.11.1 → mapfolding-0.11.3}/mapFolding/dataBaskets.py +24 -2
- {mapfolding-0.11.1 → mapfolding-0.11.3}/mapFolding/datatypes.py +0 -3
- mapfolding-0.11.1/mapFolding/toolboxFilesystem.py → mapfolding-0.11.3/mapFolding/filesystemToolkit.py +3 -3
- {mapfolding-0.11.1 → mapfolding-0.11.3}/mapFolding/oeis.py +3 -5
- mapfolding-0.11.3/mapFolding/someAssemblyRequired/RecipeJob.py +89 -0
- mapfolding-0.11.3/mapFolding/someAssemblyRequired/Z0Z_makeAllModules.py +492 -0
- {mapfolding-0.11.1 → mapfolding-0.11.3}/mapFolding/someAssemblyRequired/__init__.py +5 -31
- {mapfolding-0.11.1 → mapfolding-0.11.3}/mapFolding/someAssemblyRequired/_toolIfThis.py +5 -6
- mapfolding-0.11.1/mapFolding/someAssemblyRequired/_toolboxContainers.py → mapfolding-0.11.3/mapFolding/someAssemblyRequired/_toolkitContainers.py +6 -127
- mapfolding-0.11.3/mapFolding/someAssemblyRequired/infoBooth.py +70 -0
- {mapfolding-0.11.1 → mapfolding-0.11.3}/mapFolding/someAssemblyRequired/makeJobTheorem2Numba.py +13 -12
- mapfolding-0.11.1/mapFolding/someAssemblyRequired/toolboxNumba.py → mapfolding-0.11.3/mapFolding/someAssemblyRequired/toolkitNumba.py +2 -44
- mapfolding-0.11.3/mapFolding/someAssemblyRequired/transformationTools.py +138 -0
- mapfolding-0.11.3/mapFolding/syntheticModules/countParallel.py +98 -0
- {mapfolding-0.11.1 → mapfolding-0.11.3}/mapFolding/syntheticModules/dataPacking.py +1 -1
- mapfolding-0.11.3/mapFolding/theSSOT.py +34 -0
- {mapfolding-0.11.1 → mapfolding-0.11.3}/mapFolding.egg-info/PKG-INFO +16 -11
- {mapfolding-0.11.1 → mapfolding-0.11.3}/mapFolding.egg-info/SOURCES.txt +6 -7
- {mapfolding-0.11.1 → mapfolding-0.11.3}/mapFolding.egg-info/requires.txt +0 -3
- {mapfolding-0.11.1 → mapfolding-0.11.3}/pyproject.toml +2 -5
- {mapfolding-0.11.1 → mapfolding-0.11.3}/tests/conftest.py +2 -79
- {mapfolding-0.11.1 → mapfolding-0.11.3}/tests/test_computations.py +12 -19
- {mapfolding-0.11.1 → mapfolding-0.11.3}/tests/test_filesystem.py +1 -2
- {mapfolding-0.11.1 → mapfolding-0.11.3}/tests/test_other.py +1 -1
- {mapfolding-0.11.1 → mapfolding-0.11.3}/tests/test_tasks.py +3 -4
- mapfolding-0.11.1/mapFolding/__init__.py +0 -115
- mapfolding-0.11.1/mapFolding/someAssemblyRequired/RecipeJob.py +0 -197
- mapfolding-0.11.1/mapFolding/someAssemblyRequired/Z0Z_makeSomeModules.py +0 -325
- mapfolding-0.11.1/mapFolding/someAssemblyRequired/synthesizeNumbaJob.py +0 -314
- mapfolding-0.11.1/mapFolding/someAssemblyRequired/transformationTools.py +0 -296
- mapfolding-0.11.1/mapFolding/syntheticModules/numbaCount.py +0 -201
- mapfolding-0.11.1/mapFolding/theDao.py +0 -243
- mapfolding-0.11.1/mapFolding/theSSOT.py +0 -268
- {mapfolding-0.11.1 → mapfolding-0.11.3}/LICENSE +0 -0
- {mapfolding-0.11.1 → mapfolding-0.11.3}/mapFolding/daoOfMapFolding.py +0 -0
- {mapfolding-0.11.1 → mapfolding-0.11.3}/mapFolding/py.typed +0 -0
- {mapfolding-0.11.1 → mapfolding-0.11.3}/mapFolding/reference/__init__.py +0 -0
- {mapfolding-0.11.1 → mapfolding-0.11.3}/mapFolding/reference/flattened.py +0 -0
- {mapfolding-0.11.1 → mapfolding-0.11.3}/mapFolding/reference/hunterNumba.py +0 -0
- {mapfolding-0.11.1 → mapfolding-0.11.3}/mapFolding/reference/irvineJavaPort.py +0 -0
- {mapfolding-0.11.1 → mapfolding-0.11.3}/mapFolding/reference/jaxCount.py +0 -0
- {mapfolding-0.11.1 → mapfolding-0.11.3}/mapFolding/reference/jobsCompleted/[2x19]/p2x19.py +0 -0
- {mapfolding-0.11.1 → mapfolding-0.11.3}/mapFolding/reference/jobsCompleted/__init__.py +0 -0
- {mapfolding-0.11.1 → mapfolding-0.11.3}/mapFolding/reference/jobsCompleted/p2x19/p2x19.py +0 -0
- {mapfolding-0.11.1 → mapfolding-0.11.3}/mapFolding/reference/lunnonNumpy.py +0 -0
- {mapfolding-0.11.1 → mapfolding-0.11.3}/mapFolding/reference/lunnonWhile.py +0 -0
- {mapfolding-0.11.1 → mapfolding-0.11.3}/mapFolding/reference/rotatedEntryPoint.py +0 -0
- {mapfolding-0.11.1 → mapfolding-0.11.3}/mapFolding/reference/total_countPlus1vsPlusN.py +0 -0
- {mapfolding-0.11.1 → mapfolding-0.11.3}/mapFolding/someAssemblyRequired/getLLVMforNoReason.py +0 -0
- {mapfolding-0.11.1 → mapfolding-0.11.3}/mapFolding/syntheticModules/__init__.py +0 -0
- {mapfolding-0.11.1 → mapfolding-0.11.3}/mapFolding/syntheticModules/daoOfMapFolding.py +0 -0
- {mapfolding-0.11.1 → mapfolding-0.11.3}/mapFolding/syntheticModules/initializeCount.py +0 -0
- {mapfolding-0.11.1 → mapfolding-0.11.3}/mapFolding/syntheticModules/theorem2.py +0 -0
- {mapfolding-0.11.1 → mapfolding-0.11.3}/mapFolding/syntheticModules/theorem2Numba.py +0 -0
- {mapfolding-0.11.1 → mapfolding-0.11.3}/mapFolding/syntheticModules/theorem2Trimmed.py +0 -0
- {mapfolding-0.11.1 → mapfolding-0.11.3}/mapFolding.egg-info/dependency_links.txt +0 -0
- {mapfolding-0.11.1 → mapfolding-0.11.3}/mapFolding.egg-info/entry_points.txt +0 -0
- {mapfolding-0.11.1 → mapfolding-0.11.3}/mapFolding.egg-info/top_level.txt +0 -0
- {mapfolding-0.11.1 → mapfolding-0.11.3}/setup.cfg +0 -0
- {mapfolding-0.11.1 → mapfolding-0.11.3}/tests/__init__.py +0 -0
- {mapfolding-0.11.1 → mapfolding-0.11.3}/tests/test_oeis.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mapFolding
|
|
3
|
-
Version: 0.11.
|
|
3
|
+
Version: 0.11.3
|
|
4
4
|
Summary: Map folding algorithm with code transformation framework for optimizing numerical computations
|
|
5
5
|
Author-email: Hunter Hogan <HunterHogan@pm.me>
|
|
6
6
|
License: CC-BY-NC-4.0
|
|
@@ -33,8 +33,6 @@ Description-Content-Type: text/markdown
|
|
|
33
33
|
License-File: LICENSE
|
|
34
34
|
Requires-Dist: astToolkit
|
|
35
35
|
Requires-Dist: autoflake
|
|
36
|
-
Requires-Dist: cytoolz
|
|
37
|
-
Requires-Dist: more_itertools
|
|
38
36
|
Requires-Dist: numba_progress
|
|
39
37
|
Requires-Dist: numba
|
|
40
38
|
Requires-Dist: numpy
|
|
@@ -42,7 +40,6 @@ Requires-Dist: platformdirs
|
|
|
42
40
|
Requires-Dist: python_minifier
|
|
43
41
|
Requires-Dist: sympy
|
|
44
42
|
Requires-Dist: tomli
|
|
45
|
-
Requires-Dist: typeshed_client
|
|
46
43
|
Requires-Dist: Z0Z_tools
|
|
47
44
|
Provides-Extra: testing
|
|
48
45
|
Requires-Dist: mypy; extra == "testing"
|
|
@@ -67,12 +64,6 @@ Dynamic: license-file
|
|
|
67
64
|
- You're interested in solving mathematical puzzles through code
|
|
68
65
|
- You're learning about Numba and advanced Python optimization
|
|
69
66
|
|
|
70
|
-
**This package is NOT for you if:**
|
|
71
|
-
|
|
72
|
-
- You're looking for a general-purpose folding simulation tool
|
|
73
|
-
- You need commercial-ready mapping software
|
|
74
|
-
- You want simple visualization of folding patterns
|
|
75
|
-
|
|
76
67
|
## What Does This Package Actually Do?
|
|
77
68
|
|
|
78
69
|
`mapFolding` solves a specific mathematical problem: counting the number of distinct ways to fold a rectangular map. While this may sound niche, it's a fascinating computational challenge that demonstrates:
|
|
@@ -87,7 +78,7 @@ The package has achieved new computational records, including first-ever calcula
|
|
|
87
78
|
```python
|
|
88
79
|
# Compute the number of ways to fold a 5×5 grid:
|
|
89
80
|
from mapFolding import oeisIDfor_n
|
|
90
|
-
foldsTotal = oeisIDfor_n('A001418', 5)
|
|
81
|
+
foldsTotal = oeisIDfor_n('A001418', 5)
|
|
91
82
|
```
|
|
92
83
|
|
|
93
84
|
## Key Benefits for Computational Enthusiasts
|
|
@@ -178,4 +169,18 @@ If you've read this far and are intrigued by computational puzzles, algorithm op
|
|
|
178
169
|
|
|
179
170
|
Whether you use it to solve map folding problems or to study its optimization techniques, `mapFolding` offers a unique window into advanced Python programming approaches.
|
|
180
171
|
|
|
172
|
+
## My recovery
|
|
173
|
+
|
|
174
|
+
[](https://HunterThinks.com/support)
|
|
175
|
+
[](https://www.youtube.com/@HunterHogan)
|
|
176
|
+
|
|
177
|
+
## How to code
|
|
178
|
+
|
|
179
|
+
Coding One Step at a Time:
|
|
180
|
+
|
|
181
|
+
0. WRITE CODE.
|
|
182
|
+
1. Don't write stupid code that's hard to revise.
|
|
183
|
+
2. Write good code.
|
|
184
|
+
3. When revising, write better code.
|
|
185
|
+
|
|
181
186
|
[](https://creativecommons.org/licenses/by-nc/4.0/)
|
|
@@ -11,12 +11,6 @@
|
|
|
11
11
|
- You're interested in solving mathematical puzzles through code
|
|
12
12
|
- You're learning about Numba and advanced Python optimization
|
|
13
13
|
|
|
14
|
-
**This package is NOT for you if:**
|
|
15
|
-
|
|
16
|
-
- You're looking for a general-purpose folding simulation tool
|
|
17
|
-
- You need commercial-ready mapping software
|
|
18
|
-
- You want simple visualization of folding patterns
|
|
19
|
-
|
|
20
14
|
## What Does This Package Actually Do?
|
|
21
15
|
|
|
22
16
|
`mapFolding` solves a specific mathematical problem: counting the number of distinct ways to fold a rectangular map. While this may sound niche, it's a fascinating computational challenge that demonstrates:
|
|
@@ -31,7 +25,7 @@ The package has achieved new computational records, including first-ever calcula
|
|
|
31
25
|
```python
|
|
32
26
|
# Compute the number of ways to fold a 5×5 grid:
|
|
33
27
|
from mapFolding import oeisIDfor_n
|
|
34
|
-
foldsTotal = oeisIDfor_n('A001418', 5)
|
|
28
|
+
foldsTotal = oeisIDfor_n('A001418', 5)
|
|
35
29
|
```
|
|
36
30
|
|
|
37
31
|
## Key Benefits for Computational Enthusiasts
|
|
@@ -122,4 +116,18 @@ If you've read this far and are intrigued by computational puzzles, algorithm op
|
|
|
122
116
|
|
|
123
117
|
Whether you use it to solve map folding problems or to study its optimization techniques, `mapFolding` offers a unique window into advanced Python programming approaches.
|
|
124
118
|
|
|
119
|
+
## My recovery
|
|
120
|
+
|
|
121
|
+
[](https://HunterThinks.com/support)
|
|
122
|
+
[](https://www.youtube.com/@HunterHogan)
|
|
123
|
+
|
|
124
|
+
## How to code
|
|
125
|
+
|
|
126
|
+
Coding One Step at a Time:
|
|
127
|
+
|
|
128
|
+
0. WRITE CODE.
|
|
129
|
+
1. Don't write stupid code that's hard to revise.
|
|
130
|
+
2. Write good code.
|
|
131
|
+
3. When revising, write better code.
|
|
132
|
+
|
|
125
133
|
[](https://creativecommons.org/licenses/by-nc/4.0/)
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
from typing import Any, TypeAlias
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
yourPythonIsOld: TypeAlias = Any
|
|
5
|
+
# ruff: noqa: E402
|
|
6
|
+
|
|
7
|
+
if sys.version_info >= (3, 11):
|
|
8
|
+
from typing import TypedDict as TypedDict
|
|
9
|
+
from typing import NotRequired as NotRequired
|
|
10
|
+
else:
|
|
11
|
+
try:
|
|
12
|
+
from typing_extensions import TypedDict as TypedDict
|
|
13
|
+
from typing_extensions import NotRequired as NotRequired
|
|
14
|
+
except Exception:
|
|
15
|
+
TypedDict = dict[yourPythonIsOld, yourPythonIsOld]
|
|
16
|
+
from collections.abc import Iterable
|
|
17
|
+
NotRequired: TypeAlias = Iterable
|
|
18
|
+
|
|
19
|
+
from mapFolding.datatypes import (
|
|
20
|
+
Array1DElephino as Array1DElephino,
|
|
21
|
+
Array1DFoldsTotal as Array1DFoldsTotal,
|
|
22
|
+
Array1DLeavesTotal as Array1DLeavesTotal,
|
|
23
|
+
Array3D as Array3D,
|
|
24
|
+
DatatypeElephino as DatatypeElephino,
|
|
25
|
+
DatatypeFoldsTotal as DatatypeFoldsTotal,
|
|
26
|
+
DatatypeLeavesTotal as DatatypeLeavesTotal,
|
|
27
|
+
NumPyElephino as NumPyElephino,
|
|
28
|
+
NumPyFoldsTotal as NumPyFoldsTotal,
|
|
29
|
+
NumPyIntegerType as NumPyIntegerType,
|
|
30
|
+
NumPyLeavesTotal as NumPyLeavesTotal,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
from mapFolding.theSSOT import PackageSettings as PackageSettings, packageSettings as packageSettings
|
|
34
|
+
|
|
35
|
+
from mapFolding.beDRY import (
|
|
36
|
+
getConnectionGraph as getConnectionGraph,
|
|
37
|
+
getLeavesTotal as getLeavesTotal,
|
|
38
|
+
getTaskDivisions as getTaskDivisions,
|
|
39
|
+
makeDataContainer as makeDataContainer,
|
|
40
|
+
setProcessorLimit as setProcessorLimit,
|
|
41
|
+
validateListDimensions as validateListDimensions,
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
from mapFolding.dataBaskets import MapFoldingState as MapFoldingState
|
|
45
|
+
|
|
46
|
+
from mapFolding.filesystemToolkit import (
|
|
47
|
+
getFilenameFoldsTotal as getFilenameFoldsTotal,
|
|
48
|
+
getPathFilenameFoldsTotal as getPathFilenameFoldsTotal,
|
|
49
|
+
getPathRootJobDEFAULT as getPathRootJobDEFAULT,
|
|
50
|
+
saveFoldsTotal as saveFoldsTotal,
|
|
51
|
+
saveFoldsTotalFAILearly as saveFoldsTotalFAILearly,
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
from mapFolding.basecamp import countFolds as countFolds
|
|
55
|
+
|
|
56
|
+
from mapFolding.oeis import (
|
|
57
|
+
clearOEIScache as clearOEIScache,
|
|
58
|
+
getFoldsTotalKnown as getFoldsTotalKnown,
|
|
59
|
+
getOEISids as getOEISids,
|
|
60
|
+
OEIS_for_n as OEIS_for_n,
|
|
61
|
+
oeisIDfor_n as oeisIDfor_n,
|
|
62
|
+
)
|
|
@@ -11,13 +11,11 @@ appropriate algorithm implementation, and optional persistence of results.
|
|
|
11
11
|
|
|
12
12
|
from collections.abc import Sequence
|
|
13
13
|
from mapFolding import (
|
|
14
|
-
ComputationState,
|
|
15
14
|
getPathFilenameFoldsTotal,
|
|
16
|
-
|
|
15
|
+
packageSettings,
|
|
17
16
|
saveFoldsTotal,
|
|
18
17
|
saveFoldsTotalFAILearly,
|
|
19
18
|
setProcessorLimit,
|
|
20
|
-
The,
|
|
21
19
|
validateListDimensions,
|
|
22
20
|
)
|
|
23
21
|
from os import PathLike
|
|
@@ -104,8 +102,7 @@ def countFolds(listDimensions: Sequence[int] | None = None
|
|
|
104
102
|
# task division instructions ===============================================
|
|
105
103
|
|
|
106
104
|
if computationDivisions:
|
|
107
|
-
|
|
108
|
-
concurrencyLimit: int = setProcessorLimit(CPUlimit, The.concurrencyPackage)
|
|
105
|
+
concurrencyLimit: int = setProcessorLimit(CPUlimit, packageSettings.concurrencyPackage)
|
|
109
106
|
from mapFolding.beDRY import getLeavesTotal, getTaskDivisions
|
|
110
107
|
leavesTotal: int = getLeavesTotal(mapShape)
|
|
111
108
|
taskDivisions = getTaskDivisions(computationDivisions, concurrencyLimit, leavesTotal)
|
|
@@ -163,20 +160,25 @@ def countFolds(listDimensions: Sequence[int] | None = None
|
|
|
163
160
|
from mapFolding.syntheticModules.initializeCount import initializeGroupsOfFolds
|
|
164
161
|
mapFoldingState = initializeGroupsOfFolds(mapFoldingState)
|
|
165
162
|
|
|
166
|
-
from mapFolding.syntheticModules.dataPacking import
|
|
167
|
-
mapFoldingState =
|
|
163
|
+
from mapFolding.syntheticModules.dataPacking import sequential
|
|
164
|
+
mapFoldingState = sequential(mapFoldingState)
|
|
168
165
|
|
|
169
166
|
foldsTotal = mapFoldingState.foldsTotal
|
|
170
167
|
|
|
171
|
-
|
|
172
|
-
|
|
168
|
+
elif taskDivisions > 1:
|
|
169
|
+
from mapFolding.dataBaskets import ParallelMapFoldingState
|
|
170
|
+
parallelMapFoldingState: ParallelMapFoldingState = ParallelMapFoldingState(mapShape, taskDivisions=taskDivisions)
|
|
171
|
+
|
|
172
|
+
from mapFolding.syntheticModules.countParallel import doTheNeedful
|
|
173
|
+
foldsTotal, listStatesParallel = doTheNeedful(parallelMapFoldingState, concurrencyLimit)
|
|
173
174
|
|
|
174
175
|
else:
|
|
175
|
-
|
|
176
|
-
|
|
176
|
+
from mapFolding.dataBaskets import MapFoldingState
|
|
177
|
+
mapFoldingState: MapFoldingState = MapFoldingState(mapShape)
|
|
177
178
|
|
|
178
|
-
|
|
179
|
-
|
|
179
|
+
from mapFolding.syntheticModules.daoOfMapFolding import doTheNeedful
|
|
180
|
+
mapFoldingState = doTheNeedful(mapFoldingState)
|
|
181
|
+
foldsTotal = mapFoldingState.foldsTotal
|
|
180
182
|
|
|
181
183
|
# Follow memorialization instructions ===========================================
|
|
182
184
|
|
|
@@ -18,12 +18,13 @@ These utilities form a stable internal API that other modules depend on, particu
|
|
|
18
18
|
theDao (core algorithm), and the synthetic module generators that produce optimized implementations.
|
|
19
19
|
"""
|
|
20
20
|
from collections.abc import Sequence
|
|
21
|
-
from mapFolding import
|
|
21
|
+
from mapFolding import Array1DElephino, Array1DFoldsTotal, Array1DLeavesTotal, Array3D, DatatypeElephino, DatatypeFoldsTotal, DatatypeLeavesTotal, NumPyIntegerType
|
|
22
22
|
from numpy import dtype as numpy_dtype, int64 as numpy_int64, ndarray
|
|
23
23
|
from sys import maxsize as sysMaxsize
|
|
24
24
|
from typing import Any
|
|
25
25
|
from Z0Z_tools import defineConcurrencyLimit, intInnit, oopsieKwargsie
|
|
26
26
|
import numpy
|
|
27
|
+
import dataclasses
|
|
27
28
|
|
|
28
29
|
def getLeavesTotal(mapShape: tuple[int, ...]) -> int:
|
|
29
30
|
"""
|
|
@@ -59,7 +60,6 @@ def getTaskDivisions(computationDivisions: int | str | None, concurrencyLimit: i
|
|
|
59
60
|
"""
|
|
60
61
|
Determines whether to divide the computation into tasks and how many divisions.
|
|
61
62
|
|
|
62
|
-
|
|
63
63
|
Parameters
|
|
64
64
|
----------
|
|
65
65
|
computationDivisions: None
|
|
@@ -208,39 +208,6 @@ def makeDataContainer(shape: int | tuple[int, ...], datatype: type[NumPyIntegerT
|
|
|
208
208
|
"""
|
|
209
209
|
return numpy.zeros(shape, dtype=datatype)
|
|
210
210
|
|
|
211
|
-
def outfitCountFolds(mapShape: tuple[int, ...], computationDivisions: int | str | None = None, concurrencyLimit: int = 1) -> ComputationState:
|
|
212
|
-
"""
|
|
213
|
-
Initialize a `ComputationState` with validated parameters for map folding calculation.
|
|
214
|
-
|
|
215
|
-
This function serves as the central initialization point for creating a properly configured `ComputationState`
|
|
216
|
-
object, ensuring consistent calculation of the fundamental parameters (`leavesTotal` and `taskDivisions`) across the
|
|
217
|
-
entire package.
|
|
218
|
-
|
|
219
|
-
Parameters
|
|
220
|
-
----------
|
|
221
|
-
mapShape
|
|
222
|
-
A tuple of integers representing the dimensions of the map.
|
|
223
|
-
computationDivisions: None
|
|
224
|
-
Controls how to divide the computation into parallel tasks. I know it is annoying, but please see
|
|
225
|
-
`countFolds` for details, so that you and I both know you have the most accurate information.
|
|
226
|
-
concurrencyLimit: 1
|
|
227
|
-
Maximum number of concurrent processes to use during computation.
|
|
228
|
-
|
|
229
|
-
Returns
|
|
230
|
-
-------
|
|
231
|
-
computationStateInitialized
|
|
232
|
-
A fully initialized `ComputationState` object that's ready for computation.
|
|
233
|
-
|
|
234
|
-
Notes
|
|
235
|
-
-----
|
|
236
|
-
This function maintains the Single Source of Truth principle for `leavesTotal` and `taskDivisions` calculation,
|
|
237
|
-
ensuring these values are derived consistently throughout the package.
|
|
238
|
-
"""
|
|
239
|
-
leavesTotal = getLeavesTotal(mapShape)
|
|
240
|
-
taskDivisions = getTaskDivisions(computationDivisions, concurrencyLimit, leavesTotal)
|
|
241
|
-
computationStateInitialized = ComputationState(mapShape, leavesTotal, taskDivisions, concurrencyLimit)
|
|
242
|
-
return computationStateInitialized
|
|
243
|
-
|
|
244
211
|
def setProcessorLimit(CPUlimit: Any | None, concurrencyPackage: str | None = None) -> int:
|
|
245
212
|
"""
|
|
246
213
|
Whether and how to limit the CPU usage.
|
|
@@ -281,7 +248,8 @@ def setProcessorLimit(CPUlimit: Any | None, concurrencyPackage: str | None = Non
|
|
|
281
248
|
|
|
282
249
|
match concurrencyPackage:
|
|
283
250
|
case 'multiprocessing' | None:
|
|
284
|
-
# When to use multiprocessing.set_start_method
|
|
251
|
+
# When to use multiprocessing.set_start_method
|
|
252
|
+
# https://github.com/hunterhogan/mapFolding/issues/6
|
|
285
253
|
concurrencyLimit: int = defineConcurrencyLimit(CPUlimit)
|
|
286
254
|
case 'numba':
|
|
287
255
|
from numba import get_num_threads, set_num_threads
|
|
@@ -1,5 +1,14 @@
|
|
|
1
|
-
from mapFolding
|
|
2
|
-
|
|
1
|
+
from mapFolding import (
|
|
2
|
+
Array1DElephino,
|
|
3
|
+
Array1DLeavesTotal,
|
|
4
|
+
Array3D,
|
|
5
|
+
DatatypeElephino,
|
|
6
|
+
DatatypeFoldsTotal,
|
|
7
|
+
DatatypeLeavesTotal,
|
|
8
|
+
getConnectionGraph,
|
|
9
|
+
getLeavesTotal,
|
|
10
|
+
makeDataContainer,
|
|
11
|
+
)
|
|
3
12
|
import dataclasses
|
|
4
13
|
|
|
5
14
|
@dataclasses.dataclass
|
|
@@ -48,6 +57,19 @@ class MapFoldingState:
|
|
|
48
57
|
if self.leafAbove is None: self.leafAbove = makeDataContainer(leavesTotalAsInt + 1, self.__dataclass_fields__['leafAbove'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison]
|
|
49
58
|
if self.leafBelow is None: self.leafBelow = makeDataContainer(leavesTotalAsInt + 1, self.__dataclass_fields__['leafBelow'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison]
|
|
50
59
|
|
|
60
|
+
@dataclasses.dataclass
|
|
61
|
+
class ParallelMapFoldingState(MapFoldingState):
|
|
62
|
+
taskDivisions: DatatypeLeavesTotal = DatatypeLeavesTotal(0)
|
|
63
|
+
"""Number of tasks into which to divide the computation. If the value is greater than `leavesTotal`, the computation will be wrong. Default is `leavesTotal`."""
|
|
64
|
+
|
|
65
|
+
taskIndex: DatatypeLeavesTotal = DatatypeLeavesTotal(0)
|
|
66
|
+
"""Index of the current task when using task divisions."""
|
|
67
|
+
|
|
68
|
+
def __post_init__(self) -> None:
|
|
69
|
+
super().__post_init__()
|
|
70
|
+
if self.taskDivisions == 0:
|
|
71
|
+
self.taskDivisions = DatatypeLeavesTotal(int(self.leavesTotal))
|
|
72
|
+
|
|
51
73
|
@dataclasses.dataclass
|
|
52
74
|
class LeafSequenceState(MapFoldingState):
|
|
53
75
|
leafSequence: Array1DLeavesTotal = dataclasses.field(default=None, init=True, metadata={'dtype': Array1DLeavesTotal.__args__[1].__args__[0]}) # pyright: ignore[reportAssignmentType, reportAttributeAccessIssue, reportUnknownMemberType]
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
from numpy import dtype, uint8 as numpy_uint8, uint16 as numpy_uint16, uint64 as numpy_uint64, integer, ndarray
|
|
2
2
|
from typing import Any, TypeAlias, TypeVar
|
|
3
3
|
|
|
4
|
-
# =============================================================================
|
|
5
|
-
# Flexible Data Structure System Needs Enhanced Paradigm https://github.com/hunterhogan/mapFolding/issues/9
|
|
6
|
-
|
|
7
4
|
NumPyIntegerType = TypeVar('NumPyIntegerType', bound=integer[Any], covariant=True)
|
|
8
5
|
|
|
9
6
|
DatatypeLeavesTotal: TypeAlias = int
|
|
@@ -21,7 +21,7 @@ The functions here adhere to a consistent approach to path handling:
|
|
|
21
21
|
- Progressive fallback strategies for saving critical computation results.
|
|
22
22
|
- Preemptive filesystem validation to detect issues before computation begins.
|
|
23
23
|
"""
|
|
24
|
-
from mapFolding import
|
|
24
|
+
from mapFolding import packageSettings
|
|
25
25
|
from os import PathLike
|
|
26
26
|
from pathlib import Path, PurePath
|
|
27
27
|
from sys import modules as sysModules
|
|
@@ -101,9 +101,9 @@ def getPathRootJobDEFAULT() -> Path:
|
|
|
101
101
|
- For Google Colab, uses a specific path in Google Drive.
|
|
102
102
|
- Creates the directory if it doesn't exist.
|
|
103
103
|
"""
|
|
104
|
-
pathJobDEFAULT = Path(platformdirs.user_data_dir(appname=
|
|
104
|
+
pathJobDEFAULT = Path(platformdirs.user_data_dir(appname=packageSettings.packageName, appauthor=False, ensure_exists=True))
|
|
105
105
|
if 'google.colab' in sysModules:
|
|
106
|
-
pathJobDEFAULT = Path("/content/drive/MyDrive") /
|
|
106
|
+
pathJobDEFAULT = Path("/content/drive/MyDrive") / packageSettings.packageName
|
|
107
107
|
pathJobDEFAULT.mkdir(parents=True, exist_ok=True)
|
|
108
108
|
return pathJobDEFAULT
|
|
109
109
|
|
|
@@ -20,9 +20,10 @@ mathematical definition in OEIS and the computational implementation in the pack
|
|
|
20
20
|
from collections.abc import Callable
|
|
21
21
|
from datetime import datetime, timedelta
|
|
22
22
|
from functools import cache
|
|
23
|
-
from mapFolding import countFolds,
|
|
23
|
+
from mapFolding import countFolds, packageSettings, TypedDict
|
|
24
24
|
from pathlib import Path
|
|
25
25
|
from typing import Any, Final
|
|
26
|
+
from Z0Z_tools import writeStringToHere
|
|
26
27
|
import argparse
|
|
27
28
|
import random
|
|
28
29
|
import sys
|
|
@@ -33,7 +34,7 @@ import warnings
|
|
|
33
34
|
|
|
34
35
|
cacheDays = 30
|
|
35
36
|
|
|
36
|
-
pathCache: Path =
|
|
37
|
+
pathCache: Path = packageSettings.pathPackage / ".cache"
|
|
37
38
|
|
|
38
39
|
class SettingsOEIS(TypedDict):
|
|
39
40
|
description: str
|
|
@@ -143,9 +144,6 @@ def _parseBFileOEIS(OEISbFile: str, oeisID: str) -> dict[int, int]:
|
|
|
143
144
|
invalid.
|
|
144
145
|
"""
|
|
145
146
|
bFileLines: list[str] = OEISbFile.strip().splitlines()
|
|
146
|
-
# if not bFileLines.pop(0).startswith(f"# {oeisID}"):
|
|
147
|
-
# warnings.warn(f"Content does not match sequence {oeisID}")
|
|
148
|
-
# return {-1: -1}
|
|
149
147
|
|
|
150
148
|
OEISsequence: dict[int, int] = {}
|
|
151
149
|
for line in bFileLines:
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
from astToolkit import ast_Identifier, parseLogicalPath2astModule, str_nameDOTname
|
|
2
|
+
from mapFolding import getPathFilenameFoldsTotal, getPathRootJobDEFAULT, MapFoldingState
|
|
3
|
+
from mapFolding import DatatypeElephino as TheDatatypeElephino, DatatypeFoldsTotal as TheDatatypeFoldsTotal, DatatypeLeavesTotal as TheDatatypeLeavesTotal
|
|
4
|
+
from mapFolding.someAssemblyRequired import ShatteredDataclass, packageInformation
|
|
5
|
+
from mapFolding.someAssemblyRequired.transformationTools import shatter_dataclassesDOTdataclass
|
|
6
|
+
from pathlib import Path, PurePosixPath
|
|
7
|
+
from typing import TypeAlias
|
|
8
|
+
import dataclasses
|
|
9
|
+
|
|
10
|
+
@dataclasses.dataclass
|
|
11
|
+
class RecipeJobTheorem2Numba:
|
|
12
|
+
state: MapFoldingState
|
|
13
|
+
# TODO create function to calculate `foldsTotalEstimated`
|
|
14
|
+
foldsTotalEstimated: int = 0
|
|
15
|
+
shatteredDataclass: ShatteredDataclass = dataclasses.field(default=None, init=True) # pyright: ignore[reportAssignmentType]
|
|
16
|
+
|
|
17
|
+
# ========================================
|
|
18
|
+
# Source
|
|
19
|
+
source_astModule = parseLogicalPath2astModule('mapFolding.syntheticModules.theorem2Numba')
|
|
20
|
+
sourceCountCallable: ast_Identifier = 'count'
|
|
21
|
+
|
|
22
|
+
sourceLogicalPathModuleDataclass: str_nameDOTname = 'mapFolding.dataBaskets'
|
|
23
|
+
sourceDataclassIdentifier: ast_Identifier = 'MapFoldingState'
|
|
24
|
+
sourceDataclassInstance: ast_Identifier = packageInformation.dataclassInstance
|
|
25
|
+
|
|
26
|
+
sourcePathPackage: PurePosixPath | None = PurePosixPath(packageInformation.pathPackage)
|
|
27
|
+
sourcePackageIdentifier: ast_Identifier | None = packageInformation.packageName
|
|
28
|
+
|
|
29
|
+
# ========================================
|
|
30
|
+
# Filesystem (names of physical objects)
|
|
31
|
+
pathPackage: PurePosixPath | None = None
|
|
32
|
+
pathModule: PurePosixPath | None = PurePosixPath(getPathRootJobDEFAULT())
|
|
33
|
+
""" `pathModule` will override `pathPackage` and `logicalPathRoot`."""
|
|
34
|
+
fileExtension: str = packageInformation.fileExtension
|
|
35
|
+
pathFilenameFoldsTotal: PurePosixPath = dataclasses.field(default=None, init=True) # pyright: ignore[reportAssignmentType]
|
|
36
|
+
|
|
37
|
+
# ========================================
|
|
38
|
+
# Logical identifiers (as opposed to physical identifiers)
|
|
39
|
+
packageIdentifier: ast_Identifier | None = None
|
|
40
|
+
logicalPathRoot: str_nameDOTname | None = None
|
|
41
|
+
""" `logicalPathRoot` likely corresponds to a physical filesystem directory."""
|
|
42
|
+
moduleIdentifier: ast_Identifier = dataclasses.field(default=None, init=True) # pyright: ignore[reportAssignmentType]
|
|
43
|
+
countCallable: ast_Identifier = sourceCountCallable
|
|
44
|
+
dataclassIdentifier: ast_Identifier | None = sourceDataclassIdentifier
|
|
45
|
+
dataclassInstance: ast_Identifier | None = sourceDataclassInstance
|
|
46
|
+
logicalPathModuleDataclass: str_nameDOTname | None = sourceLogicalPathModuleDataclass
|
|
47
|
+
|
|
48
|
+
# ========================================
|
|
49
|
+
# Datatypes
|
|
50
|
+
DatatypeFoldsTotal: TypeAlias = TheDatatypeFoldsTotal
|
|
51
|
+
DatatypeElephino: TypeAlias = TheDatatypeElephino
|
|
52
|
+
DatatypeLeavesTotal: TypeAlias = TheDatatypeLeavesTotal
|
|
53
|
+
|
|
54
|
+
def _makePathFilename(self,
|
|
55
|
+
pathRoot: PurePosixPath | None = None,
|
|
56
|
+
logicalPathINFIX: str_nameDOTname | None = None,
|
|
57
|
+
filenameStem: str | None = None,
|
|
58
|
+
fileExtension: str | None = None,
|
|
59
|
+
) -> PurePosixPath:
|
|
60
|
+
if pathRoot is None:
|
|
61
|
+
pathRoot = self.pathPackage or PurePosixPath(Path.cwd())
|
|
62
|
+
if logicalPathINFIX:
|
|
63
|
+
whyIsThisStillAThing: list[str] = logicalPathINFIX.split('.')
|
|
64
|
+
pathRoot = pathRoot.joinpath(*whyIsThisStillAThing)
|
|
65
|
+
if filenameStem is None:
|
|
66
|
+
filenameStem = self.moduleIdentifier
|
|
67
|
+
if fileExtension is None:
|
|
68
|
+
fileExtension = self.fileExtension
|
|
69
|
+
filename: str = filenameStem + fileExtension
|
|
70
|
+
return pathRoot.joinpath(filename)
|
|
71
|
+
|
|
72
|
+
@property
|
|
73
|
+
def pathFilenameModule(self) -> PurePosixPath:
|
|
74
|
+
if self.pathModule is None:
|
|
75
|
+
return self._makePathFilename()
|
|
76
|
+
else:
|
|
77
|
+
return self._makePathFilename(pathRoot=self.pathModule, logicalPathINFIX=None)
|
|
78
|
+
|
|
79
|
+
def __post_init__(self):
|
|
80
|
+
pathFilenameFoldsTotal = PurePosixPath(getPathFilenameFoldsTotal(self.state.mapShape))
|
|
81
|
+
|
|
82
|
+
if self.moduleIdentifier is None: # pyright: ignore[reportUnnecessaryComparison]
|
|
83
|
+
self.moduleIdentifier = pathFilenameFoldsTotal.stem
|
|
84
|
+
|
|
85
|
+
if self.pathFilenameFoldsTotal is None: # pyright: ignore[reportUnnecessaryComparison]
|
|
86
|
+
self.pathFilenameFoldsTotal = pathFilenameFoldsTotal
|
|
87
|
+
|
|
88
|
+
if self.shatteredDataclass is None and self.logicalPathModuleDataclass and self.dataclassIdentifier and self.dataclassInstance: # pyright: ignore[reportUnnecessaryComparison]
|
|
89
|
+
self.shatteredDataclass = shatter_dataclassesDOTdataclass(self.logicalPathModuleDataclass, self.dataclassIdentifier, self.dataclassInstance)
|