mapFolding 0.5.0__py3-none-any.whl → 0.6.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. mapFolding/__init__.py +96 -58
  2. mapFolding/basecamp.py +5 -7
  3. mapFolding/beDRY.py +11 -41
  4. mapFolding/oeis.py +71 -74
  5. mapFolding/theConfiguration.py +58 -0
  6. mapFolding/theDao.py +1 -1
  7. mapFolding/theSSOT.py +14 -48
  8. mapFolding/theSSOTdatatypes.py +25 -36
  9. mapFolding/theWrongWay.py +7 -0
  10. {mapFolding-0.5.0.dist-info → mapfolding-0.6.0.dist-info}/METADATA +6 -4
  11. mapfolding-0.6.0.dist-info/RECORD +16 -0
  12. {mapFolding-0.5.0.dist-info → mapfolding-0.6.0.dist-info}/WHEEL +1 -1
  13. {mapFolding-0.5.0.dist-info → mapfolding-0.6.0.dist-info}/top_level.txt +0 -1
  14. mapFolding/reference/flattened.py +0 -377
  15. mapFolding/reference/hunterNumba.py +0 -132
  16. mapFolding/reference/irvineJavaPort.py +0 -120
  17. mapFolding/reference/jax.py +0 -208
  18. mapFolding/reference/lunnan.py +0 -153
  19. mapFolding/reference/lunnanNumpy.py +0 -123
  20. mapFolding/reference/lunnanWhile.py +0 -121
  21. mapFolding/reference/rotatedEntryPoint.py +0 -240
  22. mapFolding/reference/total_countPlus1vsPlusN.py +0 -211
  23. mapFolding/someAssemblyRequired/__init__.py +0 -5
  24. mapFolding/someAssemblyRequired/getLLVMforNoReason.py +0 -19
  25. mapFolding/someAssemblyRequired/makeJob.py +0 -56
  26. mapFolding/someAssemblyRequired/synthesizeModuleJAX.py +0 -27
  27. mapFolding/someAssemblyRequired/synthesizeNumba.py +0 -345
  28. mapFolding/someAssemblyRequired/synthesizeNumbaGeneralized.py +0 -397
  29. mapFolding/someAssemblyRequired/synthesizeNumbaJob.py +0 -155
  30. mapFolding/someAssemblyRequired/synthesizeNumbaModules.py +0 -123
  31. mapFolding/syntheticModules/numbaCount.py +0 -158
  32. mapFolding/syntheticModules/numba_doTheNeedful.py +0 -13
  33. mapFolding-0.5.0.dist-info/RECORD +0 -39
  34. tests/__init__.py +0 -1
  35. tests/conftest.py +0 -335
  36. tests/test_computations.py +0 -42
  37. tests/test_oeis.py +0 -128
  38. tests/test_other.py +0 -175
  39. tests/test_tasks.py +0 -40
  40. /mapFolding/{syntheticModules/__init__.py → py.typed} +0 -0
  41. {mapFolding-0.5.0.dist-info → mapfolding-0.6.0.dist-info}/LICENSE +0 -0
  42. {mapFolding-0.5.0.dist-info → mapfolding-0.6.0.dist-info}/entry_points.txt +0 -0
@@ -1,158 +0,0 @@
1
- from mapFolding import indexTrack, indexMy
2
- from numba import int64, prange, uint16, jit
3
- from numpy import ndarray, dtype, integer
4
- from typing import 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,13 +0,0 @@
1
- from mapFolding import indexMy
2
- from mapFolding.syntheticModules.numbaCount import countInitialize, countParallel, countSequential
3
- from numba import uint16, jit, int64
4
- from numpy import ndarray, dtype, integer
5
- from typing import Any
6
-
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)
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:
9
- countInitialize(connectionGraph, gapsWhere, my, track)
10
- if my[indexMy.taskDivisions.value] > 0:
11
- countParallel(connectionGraph, foldGroups, gapsWhere, my, track)
12
- else:
13
- countSequential(connectionGraph, foldGroups, gapsWhere, my, track)
@@ -1,39 +0,0 @@
1
- mapFolding/__init__.py,sha256=AQA9ypsiV8cDUCvWdM64kFhO9LaKFvAuSEw03jiI7ao,1358
2
- mapFolding/basecamp.py,sha256=f6Z_KJ1iGV5a3YBDsxS0m7RojYABYlR4kb-dvKW8CAs,3703
3
- mapFolding/beDRY.py,sha256=ViKLdomPYXD4o86BZwWgT0qPQNKqdtAZ74YoKC9Kgjg,16793
4
- mapFolding/oeis.py,sha256=Jak0vOfS_gGTXH6xBI7NTUp4Clluvj792E5HNFDDt6U,11149
5
- mapFolding/theDao.py,sha256=64dlLhrdtNbZAXMbqcZhGAE0ZwgqYRt8nT1on46J-cc,12611
6
- mapFolding/theSSOT.py,sha256=tcEbPQLmvRWfIyuR0NpeY0Vm6l6L1dUJFyFZjbDo2Gs,6026
7
- mapFolding/theSSOTdatatypes.py,sha256=OoB9hVfedQejRPxkP-dgLMHS-vqw_0imBvMLBuyLlg0,5829
8
- mapFolding/reference/flattened.py,sha256=S6D9wiFTlbeoetEqaMLOcA-R22BHOzjqPRujffNxxUM,14875
9
- mapFolding/reference/hunterNumba.py,sha256=jDS0ORHkIhcJ1rzA5hT49sZHKf3rgJOoGesUCcbKFFY,6054
10
- mapFolding/reference/irvineJavaPort.py,sha256=7GvBU0tnS6wpFgkYad3465do9jBQW-2bYvbCYyABPHM,3341
11
- mapFolding/reference/jax.py,sha256=7ji9YWia6Kof0cjcNdiS1GG1rMbC5SBjcyVr_07AeUk,13845
12
- mapFolding/reference/lunnan.py,sha256=iAbJELfW6RKNMdPcBY9b6rGQ-z1zoRf-1XCurCRMOo8,3951
13
- mapFolding/reference/lunnanNumpy.py,sha256=rwVP3WIDXimpAuaxhRIuBYU56nVDTKlfGiclw_FkgUU,3765
14
- mapFolding/reference/lunnanWhile.py,sha256=uRrMT23jTJvoQDlD_FzeIQe_pfMXJG6_bRvs7uhC8z0,3271
15
- mapFolding/reference/rotatedEntryPoint.py,sha256=USZY3n3zwhSE68ATscUuN66t1qShuEbMI790Gz9JFTw,9352
16
- mapFolding/reference/total_countPlus1vsPlusN.py,sha256=wpgay-uqPOBd64Z4Pg6tg40j7-4pzWHGMM6v0bnmjhE,6288
17
- mapFolding/someAssemblyRequired/__init__.py,sha256=wtec_hIz-AKz0_hGdXsWnCKTcCxdMV9-WK6SiIriAeU,396
18
- mapFolding/someAssemblyRequired/getLLVMforNoReason.py,sha256=nX8tghZClYt7zJd6RpZBXhE_h-CGRHOS17biqiEdf-o,855
19
- mapFolding/someAssemblyRequired/makeJob.py,sha256=neb_sFvYMx6dlZxKVmwGjKNrEsK0XaHyE1AJD9S9-nA,2408
20
- mapFolding/someAssemblyRequired/synthesizeModuleJAX.py,sha256=21Wos8ynlly577EUDqWbbNc9R1qc19r5ysWaz86bCvg,1210
21
- mapFolding/someAssemblyRequired/synthesizeNumba.py,sha256=6bVbZMnszgz5J81KF-_LQyi6Sw9SwUBD-k8u-mFKADo,16940
22
- mapFolding/someAssemblyRequired/synthesizeNumbaGeneralized.py,sha256=vu6oYqoZGLNzbd3i8H9B2cEtL9bM1dhmbIpcJeF1NKE,16666
23
- mapFolding/someAssemblyRequired/synthesizeNumbaJob.py,sha256=YRFLuEWcE7Fz4D7vgEwwof5xsrTRY2tIFl69GrFYke8,9050
24
- mapFolding/someAssemblyRequired/synthesizeNumbaModules.py,sha256=3oUCPU4nnfynhEqSFqIC8BZ1x0lXK0_0_o-hIx8MCPw,5504
25
- mapFolding/syntheticModules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
- mapFolding/syntheticModules/numbaCount.py,sha256=447sbrCINu6wMfpJENguUyAxd6Vej3w98WzyVelz8eg,12900
27
- mapFolding/syntheticModules/numba_doTheNeedful.py,sha256=8utsCDlcIvOlrjGugaD6DgecoDICIo5_BKhkYtwv-74,1150
28
- tests/__init__.py,sha256=eg9smg-6VblOr0kisM40CpGnuDtU2JgEEWGDTFVOlW8,57
29
- tests/conftest.py,sha256=rorOpl3Q1ksGQB-8UyLdUDkYBl9O3M19CvOKrnnzr-4,12296
30
- tests/test_computations.py,sha256=67dcIj94VM69m912cY1L8HuqnXWl9NFVNhjx3zRNjvA,2831
31
- tests/test_oeis.py,sha256=4EPJrd359kO019e6whDnERU-gnvMeOeUsHFgor7bA1Y,4686
32
- tests/test_other.py,sha256=x34TGMWY7YmVtTduC_hlmISMVYemcx_z8_UcMcaNyIk,8375
33
- tests/test_tasks.py,sha256=J8CET4Z-SYZGdy1-nj-pvVqMl6ujTXJR5ZCYkU4gbUc,2389
34
- mapFolding-0.5.0.dist-info/LICENSE,sha256=NxH5Y8BdC-gNU-WSMwim3uMbID2iNDXJz7fHtuTdXhk,19346
35
- mapFolding-0.5.0.dist-info/METADATA,sha256=rLrgAmUzYgyLQV_mh749XXhiD1RLrol0iHXZpA_10DU,7678
36
- mapFolding-0.5.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
37
- mapFolding-0.5.0.dist-info/entry_points.txt,sha256=F3OUeZR1XDTpoH7k3wXuRb3KF_kXTTeYhu5AGK1SiOQ,146
38
- mapFolding-0.5.0.dist-info/top_level.txt,sha256=1gP2vFaqPwHujGwb3UjtMlLEGN-943VSYFR7V4gDqW8,17
39
- mapFolding-0.5.0.dist-info/RECORD,,
tests/__init__.py DELETED
@@ -1 +0,0 @@
1
- from tests.conftest import makeDictionaryFoldsTotalKnown
tests/conftest.py DELETED
@@ -1,335 +0,0 @@
1
- """SSOT for Pytest"""
2
-
3
- # TODO learn how to run tests and coverage analysis without `env = ["NUMBA_DISABLE_JIT=1"]`
4
-
5
- from collections.abc import Callable, Generator, Sequence
6
- from mapFolding import (
7
- getAlgorithmDispatcher,
8
- getDispatcherCallable,
9
- countFolds,
10
- getPathFilenameFoldsTotal,
11
- oeisIDfor_n,
12
- saveFoldsTotal,
13
- hackSSOTdtype,
14
- clearOEIScache,
15
- getOEISids,
16
- )
17
- from mapFolding import basecamp
18
- from mapFolding.beDRY import (
19
- getLeavesTotal,
20
- validateListDimensions,
21
- makeDataContainer,
22
- parseDimensions,
23
- setCPUlimit,
24
- makeConnectionGraph,
25
- getTaskDivisions,
26
- )
27
- from mapFolding.oeis import (
28
- oeisIDsImplemented,
29
- settingsOEIS,
30
- validateOEISid,
31
- getOEISidValues,
32
- OEIS_for_n,
33
- )
34
- from mapFolding.someAssemblyRequired import (
35
- makeFlowNumbaOptimized,
36
- youOughtaKnow,
37
- writeJobNumba,
38
- )
39
- from pathlib import Path
40
- from types import ModuleType
41
- from typing import Any, ContextManager, Literal, NoReturn, Final
42
- from Z0Z_tools.pytestForYourUse import PytestFor_defineConcurrencyLimit, PytestFor_intInnit, PytestFor_oopsieKwargsie
43
- import importlib.util
44
- import pytest
45
- import random
46
- import shutil
47
- import unittest.mock
48
- import uuid
49
-
50
- # SSOT for test data paths and filenames
51
- pathDataSamples = Path("tests/dataSamples")
52
- # NOTE `tmp` is not a diminutive form of temporary: it signals a technical term. And "temp" is strongly disfavored.
53
- pathTmpRoot: Path = pathDataSamples / "tmp"
54
-
55
- # The registrar maintains the register of temp files
56
- registerOfTemporaryFilesystemObjects: set[Path] = set()
57
-
58
- def registrarRecordsTmpObject(path: Path) -> None:
59
- """The registrar adds a tmp file to the register."""
60
- registerOfTemporaryFilesystemObjects.add(path)
61
-
62
- def registrarDeletesTmpObjects() -> None:
63
- """The registrar cleans up tmp files in the register."""
64
- for pathTmp in sorted(registerOfTemporaryFilesystemObjects, reverse=True):
65
- try:
66
- if pathTmp.is_file():
67
- pathTmp.unlink(missing_ok=True)
68
- elif pathTmp.is_dir():
69
- shutil.rmtree(pathTmp, ignore_errors=True)
70
- except Exception as ERRORmessage:
71
- print(f"Warning: Failed to clean up {pathTmp}: {ERRORmessage}")
72
- registerOfTemporaryFilesystemObjects.clear()
73
-
74
- @pytest.fixture(scope="session", autouse=True)
75
- def setupTeardownTmpObjects() -> Generator[None, None, None]:
76
- """Auto-fixture to setup test data directories and cleanup after."""
77
- pathDataSamples.mkdir(exist_ok=True)
78
- pathTmpRoot.mkdir(exist_ok=True)
79
- yield
80
- registrarDeletesTmpObjects()
81
-
82
- @pytest.fixture
83
- def pathTmpTesting(request: pytest.FixtureRequest) -> Path:
84
- # "Z0Z_" ensures the directory name does not start with a number, which would make it an invalid Python identifier
85
- pathTmp = pathTmpRoot / ("Z0Z_" + str(uuid.uuid4().hex))
86
- pathTmp.mkdir(parents=True, exist_ok=False)
87
-
88
- registrarRecordsTmpObject(pathTmp)
89
- return pathTmp
90
-
91
- @pytest.fixture
92
- def pathFilenameTmpTesting(request: pytest.FixtureRequest) -> Path:
93
- try:
94
- extension = request.param
95
- except AttributeError:
96
- extension = ".txt"
97
-
98
- # "Z0Z_" ensures the name does not start with a number, which would make it an invalid Python identifier
99
- uuidHex = uuid.uuid4().hex
100
- subpath = "Z0Z_" + uuidHex[0:-8]
101
- filenameStem = "Z0Z_" + uuidHex[-8:None]
102
-
103
- pathFilenameTmp = Path(pathTmpRoot, subpath, filenameStem + extension)
104
- pathFilenameTmp.parent.mkdir(parents=True, exist_ok=False)
105
-
106
- registrarRecordsTmpObject(pathFilenameTmp)
107
- return pathFilenameTmp
108
-
109
- @pytest.fixture
110
- def pathCacheTesting(pathTmpTesting: Path) -> Generator[Path, Any, None]:
111
- """Temporarily replace the OEIS cache directory with a test directory."""
112
- from mapFolding import oeis as there_must_be_a_better_way
113
- pathCacheOriginal = there_must_be_a_better_way._pathCache
114
- there_must_be_a_better_way._pathCache = pathTmpTesting
115
- yield pathTmpTesting
116
- there_must_be_a_better_way._pathCache = pathCacheOriginal
117
-
118
- @pytest.fixture
119
- def pathFilenameFoldsTotalTesting(pathTmpTesting: Path) -> Path:
120
- return pathTmpTesting.joinpath("foldsTotalTest.txt")
121
-
122
- def makeDictionaryFoldsTotalKnown() -> dict[tuple[int, ...], int]:
123
- """Returns a dictionary mapping dimension tuples to their known folding totals."""
124
- dictionaryMapDimensionsToFoldsTotalKnown: dict[tuple[int, ...], int] = {}
125
-
126
- for settings in settingsOEIS.values():
127
- sequence = settings['valuesKnown']
128
-
129
- for n, foldingsTotal in sequence.items():
130
- dimensions = settings['getMapShape'](n)
131
- dimensions.sort()
132
- dictionaryMapDimensionsToFoldsTotalKnown[tuple(dimensions)] = foldingsTotal
133
- return dictionaryMapDimensionsToFoldsTotalKnown
134
-
135
- """
136
- Section: Fixtures"""
137
-
138
- @pytest.fixture(autouse=True)
139
- def setupWarningsAsErrors() -> Generator[None, Any, None]:
140
- """Convert all warnings to errors for all tests."""
141
- import warnings
142
- warnings.filterwarnings("error")
143
- yield
144
- warnings.resetwarnings()
145
-
146
- @pytest.fixture
147
- def foldsTotalKnown() -> dict[tuple[int, ...], int]:
148
- """Returns a dictionary mapping dimension tuples to their known folding totals.
149
- NOTE I am not convinced this is the best way to do this.
150
- Advantage: I call `makeDictionaryFoldsTotalKnown()` from modules other than test modules.
151
- Preference: I _think_ I would prefer a SSOT function available to any module
152
- similar to `foldsTotalKnown = getFoldsTotalKnown(listDimensions)`."""
153
- return makeDictionaryFoldsTotalKnown()
154
-
155
- @pytest.fixture
156
- def listDimensionsTestCountFolds(oeisID: str) -> list[int]:
157
- """For each `oeisID` from the `pytest.fixture`, returns `listDimensions` from `valuesTestValidation`
158
- if `validateListDimensions` approves. Each `listDimensions` is suitable for testing counts."""
159
- while True:
160
- n = random.choice(settingsOEIS[oeisID]['valuesTestValidation'])
161
- if n < 2:
162
- continue
163
- listDimensionsCandidate = settingsOEIS[oeisID]['getMapShape'](n)
164
-
165
- try:
166
- return validateListDimensions(listDimensionsCandidate)
167
- except (ValueError, NotImplementedError):
168
- pass
169
-
170
- @pytest.fixture
171
- def listDimensionsTestFunctionality(oeisID_1random: str) -> list[int]:
172
- """To test functionality, get one `listDimensions` from `valuesTestValidation` if
173
- `validateListDimensions` approves. The algorithm can count the folds of the returned
174
- `listDimensions` in a short enough time suitable for testing."""
175
- while True:
176
- n = random.choice(settingsOEIS[oeisID_1random]['valuesTestValidation'])
177
- if n < 2:
178
- continue
179
- listDimensionsCandidate = settingsOEIS[oeisID_1random]['getMapShape'](n)
180
-
181
- try:
182
- return validateListDimensions(listDimensionsCandidate)
183
- except (ValueError, NotImplementedError):
184
- pass
185
-
186
- @pytest.fixture
187
- def listDimensionsTestParallelization(oeisID: str) -> list[int]:
188
- """For each `oeisID` from the `pytest.fixture`, returns `listDimensions` from `valuesTestParallelization`"""
189
- n = random.choice(settingsOEIS[oeisID]['valuesTestParallelization'])
190
- return settingsOEIS[oeisID]['getMapShape'](n)
191
-
192
- @pytest.fixture
193
- def mockBenchmarkTimer() -> Generator[unittest.mock.MagicMock | unittest.mock.AsyncMock, Any, None]:
194
- """Mock time.perf_counter_ns for consistent benchmark timing."""
195
- with unittest.mock.patch('time.perf_counter_ns') as mockTimer:
196
- mockTimer.side_effect = [0, 1e9] # Start and end times for 1 second
197
- yield mockTimer
198
-
199
- @pytest.fixture
200
- def mockFoldingFunction() -> Callable[..., Callable[..., None]]:
201
- """Creates a mock function that simulates _countFolds behavior."""
202
- def make_mock(foldsValue: int, listDimensions: list[int]) -> Callable[..., None]:
203
- mock_array = makeDataContainer(2)
204
- mock_array[0] = foldsValue
205
- mock_array[-1] = getLeavesTotal(listDimensions)
206
-
207
- def mock_countFolds(**keywordArguments: Any) -> None:
208
- keywordArguments['foldGroups'][:] = mock_array
209
- return None
210
-
211
- return mock_countFolds
212
- return make_mock
213
-
214
- @pytest.fixture
215
- def mockDispatcher() -> Callable[[Any], ContextManager[Any]]:
216
- """Context manager for mocking dispatcher callable."""
217
- def wrapper(mockFunction: Any) -> ContextManager[Any]:
218
- dispatcherCallable = getDispatcherCallable()
219
- return unittest.mock.patch(
220
- f"{dispatcherCallable.__module__}.{dispatcherCallable.__name__}",
221
- side_effect=mockFunction
222
- )
223
- return wrapper
224
-
225
- @pytest.fixture(params=oeisIDsImplemented)
226
- def oeisID(request: pytest.FixtureRequest) -> Any:
227
- return request.param
228
-
229
- @pytest.fixture
230
- def oeisID_1random() -> str:
231
- """Return one random valid OEIS ID."""
232
- return random.choice(oeisIDsImplemented)
233
-
234
- @pytest.fixture
235
- def useThisDispatcher():
236
- """A fixture providing a context manager for temporarily replacing the dispatcher.
237
-
238
- Returns
239
- A context manager for patching the dispatcher
240
- """
241
- dispatcherOriginal = basecamp.getDispatcherCallable
242
-
243
- def patchDispatcher(callableTarget: Callable) -> None:
244
- def callableParameterized(*arguments: Any, **keywordArguments: Any) -> Callable:
245
- return callableTarget
246
- basecamp.getDispatcherCallable = callableParameterized
247
-
248
- yield patchDispatcher
249
- basecamp.getDispatcherCallable = dispatcherOriginal
250
-
251
- @pytest.fixture
252
- def useAlgorithmSourceDispatcher(useThisDispatcher: Callable) -> Generator[None, None, None]:
253
- """Temporarily patches getDispatcherCallable to return the algorithm dispatcher."""
254
- useThisDispatcher(getAlgorithmDispatcher())
255
- yield
256
-
257
- @pytest.fixture
258
- def syntheticDispatcherFixture(useThisDispatcher):
259
- listCallablesInlineHARDCODED: list[str] = ['countInitialize', 'countParallel', 'countSequential']
260
- listCallablesInline = listCallablesInlineHARDCODED
261
- callableDispatcher = True
262
- algorithmSource = None
263
- relativePathWrite = None
264
- filenameModuleWrite = 'pytestCount.py'
265
- formatFilenameWrite = "pytest_{callableTarget}.py"
266
- listSynthesizedModules: list[youOughtaKnow] = makeFlowNumbaOptimized(listCallablesInline, callableDispatcher, algorithmSource, relativePathWrite, filenameModuleWrite, formatFilenameWrite)
267
- dispatcherSynthetic = youOughtaKnow('','','')
268
- for stuff in listSynthesizedModules:
269
- registrarRecordsTmpObject(stuff.pathFilenameForMe)
270
- if stuff.callableSynthesized not in listCallablesInline:
271
- dispatcherSynthetic: youOughtaKnow = stuff
272
-
273
- dispatcherSpec = importlib.util.spec_from_file_location(dispatcherSynthetic.callableSynthesized, dispatcherSynthetic.pathFilenameForMe)
274
- if dispatcherSpec is None:
275
- raise ImportError(f"{dispatcherSynthetic.pathFilenameForMe=}")
276
- if dispatcherSpec.loader is None:
277
- raise ImportError(f"Failed to get loader for module {dispatcherSynthetic.pathFilenameForMe}")
278
-
279
- dispatcherModule = importlib.util.module_from_spec(dispatcherSpec)
280
- dispatcherSpec.loader.exec_module(dispatcherModule)
281
- callableDispatcherSynthetic = getattr(dispatcherModule, dispatcherSynthetic.callableSynthesized)
282
-
283
- useThisDispatcher(callableDispatcherSynthetic)
284
- return callableDispatcherSynthetic
285
-
286
- def uniformTestMessage(expected: Any, actual: Any, functionName: str, *arguments: Any) -> str:
287
- """Format assertion message for any test comparison."""
288
- return (f"\nTesting: `{functionName}({', '.join(str(parameter) for parameter in arguments)})`\n"
289
- f"Expected: {expected}\n"
290
- f"Got: {actual}")
291
-
292
- def standardizedEqualTo(expected: Any, functionTarget: Callable, *arguments: Any) -> None:
293
- """Template for tests expecting an error."""
294
- if type(expected) is type[Exception]:
295
- messageExpected = expected.__name__
296
- else:
297
- messageExpected = expected
298
-
299
- try:
300
- messageActual = actual = functionTarget(*arguments)
301
- except Exception as actualError:
302
- messageActual = type(actualError).__name__
303
- actual = type(actualError)
304
-
305
- assert actual == expected, uniformTestMessage(messageExpected, messageActual, functionTarget.__name__, *arguments)
306
-
307
- def standardizedSystemExit(expected: str | int | Sequence[int], functionTarget: Callable, *arguments: Any) -> None:
308
- """Template for tests expecting SystemExit.
309
-
310
- Parameters
311
- expected: Exit code expectation:
312
- - "error": any non-zero exit code
313
- - "nonError": specifically zero exit code
314
- - int: exact exit code match
315
- - Sequence[int]: exit code must be one of these values
316
- functionTarget: The function to test
317
- arguments: Arguments to pass to the function
318
- """
319
- with pytest.raises(SystemExit) as exitInfo:
320
- functionTarget(*arguments)
321
-
322
- exitCode = exitInfo.value.code
323
-
324
- if expected == "error":
325
- assert exitCode != 0, \
326
- f"Expected error exit (non-zero) but got code {exitCode}"
327
- elif expected == "nonError":
328
- assert exitCode == 0, \
329
- f"Expected non-error exit (0) but got code {exitCode}"
330
- elif isinstance(expected, (list, tuple)):
331
- assert exitCode in expected, \
332
- f"Expected exit code to be one of {expected} but got {exitCode}"
333
- else:
334
- assert exitCode == expected, \
335
- f"Expected exit code {expected} but got {exitCode}"
@@ -1,42 +0,0 @@
1
- from tests.conftest import *
2
- import importlib.util
3
- import pytest
4
-
5
- def test_algorithmSourceParallel(listDimensionsTestParallelization: list[int], foldsTotalKnown: dict[tuple[int, ...], int], useAlgorithmSourceDispatcher: None) -> None:
6
- standardizedEqualTo(foldsTotalKnown[tuple(listDimensionsTestParallelization)], countFolds, listDimensionsTestParallelization, None, 'maximum')
7
-
8
- def test_algorithmSourceSequential(listDimensionsTestCountFolds: list[int], foldsTotalKnown: dict[tuple[int, ...], int], useAlgorithmSourceDispatcher: None) -> None:
9
- standardizedEqualTo(foldsTotalKnown[tuple(listDimensionsTestCountFolds)], countFolds, listDimensionsTestCountFolds)
10
-
11
- def test_aOFn_calculate_value(oeisID: str) -> None:
12
- for n in settingsOEIS[oeisID]['valuesTestValidation']:
13
- standardizedEqualTo(settingsOEIS[oeisID]['valuesKnown'][n], oeisIDfor_n, oeisID, n)
14
-
15
- @pytest.mark.parametrize('pathFilenameTmpTesting', ['.py'], indirect=True)
16
- def test_writeJobNumba(listDimensionsTestCountFolds: list[int], foldsTotalKnown: dict[tuple[int, ...], int], pathFilenameTmpTesting: Path) -> None:
17
- from mapFolding.syntheticModules import numbaCount
18
- algorithmSourceHARDCODED: ModuleType = numbaCount
19
- algorithmSource = algorithmSourceHARDCODED
20
- callableTargetHARDCODED = 'countSequential'
21
- callableTarget = callableTargetHARDCODED
22
- pathFilenameModule = writeJobNumba(listDimensionsTestCountFolds, algorithmSource, callableTarget, pathFilenameWriteJob=pathFilenameTmpTesting.absolute())
23
-
24
- Don_Lapre_Road_to_Self_Improvement = importlib.util.spec_from_file_location("__main__", pathFilenameModule)
25
- if Don_Lapre_Road_to_Self_Improvement is None:
26
- raise ImportError(f"Failed to create module specification from {pathFilenameModule}")
27
- if Don_Lapre_Road_to_Self_Improvement.loader is None:
28
- raise ImportError(f"Failed to get loader for module {pathFilenameModule}")
29
- module = importlib.util.module_from_spec(Don_Lapre_Road_to_Self_Improvement)
30
-
31
- module.__name__ = "__main__"
32
- Don_Lapre_Road_to_Self_Improvement.loader.exec_module(module)
33
-
34
- pathFilenameFoldsTotal = getPathFilenameFoldsTotal(listDimensionsTestCountFolds)
35
- registrarRecordsTmpObject(pathFilenameFoldsTotal)
36
- standardizedEqualTo(str(foldsTotalKnown[tuple(listDimensionsTestCountFolds)]), pathFilenameFoldsTotal.read_text().strip)
37
-
38
- def test_syntheticParallel(syntheticDispatcherFixture, listDimensionsTestParallelization: list[int], foldsTotalKnown: dict[tuple[int, ...], int]):
39
- standardizedEqualTo(foldsTotalKnown[tuple(listDimensionsTestParallelization)], countFolds, listDimensionsTestParallelization, None, 'maximum')
40
-
41
- def test_syntheticSequential(syntheticDispatcherFixture, listDimensionsTestCountFolds: list[int], foldsTotalKnown: dict[tuple[int, ...], int]):
42
- standardizedEqualTo(foldsTotalKnown[tuple(listDimensionsTestCountFolds)], countFolds, listDimensionsTestCountFolds)