Skip to content

Commit 13c5547

Browse files
Merge PrMers v99.90 Gaussian macOS uint64 portability fix
2 parents cd5538b + 686dc02 commit 13c5547

9 files changed

Lines changed: 393 additions & 7 deletions

.github/workflows/build_linux.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ jobs:
2929
3030
- name: Run host and routing tests
3131
run: |
32+
make test-gm
3233
make test-aevum-host
3334
make test-aevum-auto
3435
make test-aevum-default

.github/workflows/build_mac_os.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ jobs:
192192
shell: bash
193193
run: |
194194
set -euo pipefail
195+
make test-gm
195196
make test-aevum-host MACOSX_DEPLOYMENT_TARGET="$MACOSX_DEPLOYMENT_TARGET"
196197
make test-aevum-source
197198
make test-backend-compat

README_GAUSSIAN_FACTORING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Gaussian-Mersenne P-1 and ECM — PrMers v99.89
1+
# Gaussian-Mersenne P-1 and ECM — PrMers v99.90
22

33
This extension factors the Gaussian-Mersenne norm
44

Lines changed: 371 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,371 @@
1+
# PrMers v99.90 — Gaussian macOS uint64/GMP portability fix
2+
3+
PrMers version:
4+
5+
```text
6+
4.20.79-alpha-v99.90-gaussian-macos-u64-fix
7+
bash <<'BASH'
8+
set -euo pipefail
9+
10+
REPO="$HOME/prmerscopy/PrMers"
11+
BRANCH="release-prmers-v99.90-final"
12+
13+
OLD_BUILD="4.20.78-alpha-v99.89-gaussian-worktodo-progress-json"
14+
NEW_BUILD="4.20.79-alpha-v99.90-gaussian-macos-u64-fix"
15+
16+
cd "$REPO"
17+
18+
# Sauvegarder proprement le collage incomplet précédent.
19+
if test -n "$(git status --porcelain)"; then
20+
git stash push -u \
21+
-m "backup incomplete v99.90 correction $(date +%Y%m%d-%H%M%S)"
22+
fi
23+
24+
git switch main
25+
git pull --ff-only origin main
26+
git fetch --prune origin
27+
28+
test -z "$(git status --porcelain)"
29+
30+
if git ls-remote --exit-code --heads origin \
31+
"refs/heads/$BRANCH" >/dev/null 2>&1
32+
then
33+
echo "ERREUR: branche distante déjà présente : $BRANCH"
34+
exit 1
35+
fi
36+
37+
git branch -D "$BRANCH" 2>/dev/null || true
38+
git switch -c "$BRANCH"
39+
40+
python3 - "$OLD_BUILD" "$NEW_BUILD" <<'PY'
41+
from pathlib import Path
42+
import sys
43+
44+
old_build = sys.argv[1]
45+
new_build = sys.argv[2]
46+
47+
48+
def replace_once(filename: str, old: str, new: str) -> None:
49+
path = Path(filename)
50+
text = path.read_text(encoding="utf-8")
51+
count = text.count(old)
52+
53+
if count != 1:
54+
raise SystemExit(
55+
f"ERREUR: {filename}: attendu exactement 1 occurrence "
56+
f"de {old!r}, trouvé {count}"
57+
)
58+
59+
path.write_text(text.replace(old, new, 1), encoding="utf-8")
60+
61+
62+
# ---------------------------------------------------------------------------
63+
# Correction portable std::uint64_t -> GMP.
64+
# ---------------------------------------------------------------------------
65+
66+
replace_once(
67+
"src/modes/RunGaussianMersenneFactor.cpp",
68+
" mpz_class sigma = sigma64;",
69+
""" mpz_class sigma;
70+
mpz_import(
71+
sigma.get_mpz_t(),
72+
1,
73+
1,
74+
sizeof(sigma64),
75+
0,
76+
0,
77+
&sigma64);""",
78+
)
79+
80+
# ---------------------------------------------------------------------------
81+
# Version complète.
82+
# ---------------------------------------------------------------------------
83+
84+
for filename in (
85+
"include/core/Version.hpp",
86+
"tests/aevum_pow2_type4_source_test.py",
87+
"tests/gaussian_mersenne_factor_isolation_test.py",
88+
):
89+
replace_once(filename, old_build, new_build)
90+
91+
# ---------------------------------------------------------------------------
92+
# Version courte des JSON Gaussian.
93+
# ---------------------------------------------------------------------------
94+
95+
for filename in (
96+
"src/modes/RunGaussianMersenne.cpp",
97+
"src/modes/RunGaussianMersenneFactor.cpp",
98+
):
99+
replace_once(
100+
filename,
101+
'constexpr const char* GM_RELEASE = "v99.89";',
102+
'constexpr const char* GM_RELEASE = "v99.90";',
103+
)
104+
105+
# ---------------------------------------------------------------------------
106+
# Audit empêchant le retour de la conversion ambiguë.
107+
# ---------------------------------------------------------------------------
108+
109+
test_path = Path("tests/gaussian_mersenne_factor_isolation_test.py")
110+
test = test_path.read_text(encoding="utf-8")
111+
112+
marker = f'assert "{new_build}" in version\n'
113+
checks = """
114+
# GMP C++ has no portable unsigned-long-long constructor on every ABI.
115+
assert "mpz_class sigma = sigma64;" not in source
116+
assert "mpz_import(" in source
117+
assert "sizeof(sigma64)" in source
118+
"""
119+
120+
if marker not in test:
121+
raise SystemExit("ERREUR: marqueur de version absent du test Gaussian")
122+
123+
if 'assert "mpz_class sigma = sigma64;" not in source' not in test:
124+
test = test.replace(marker, marker + checks, 1)
125+
126+
test_path.write_text(test, encoding="utf-8")
127+
128+
# ---------------------------------------------------------------------------
129+
# Exécuter test-gm dans les CI Linux et macOS.
130+
# ---------------------------------------------------------------------------
131+
132+
workflow_changes = (
133+
(
134+
Path(".github/workflows/build_linux.yml"),
135+
" make test-aevum-host\n",
136+
" make test-gm\n"
137+
" make test-aevum-host\n",
138+
),
139+
(
140+
Path(".github/workflows/build_mac_os.yml"),
141+
' make test-aevum-host MACOSX_DEPLOYMENT_TARGET="$MACOSX_DEPLOYMENT_TARGET"\n',
142+
" make test-gm\n"
143+
' make test-aevum-host MACOSX_DEPLOYMENT_TARGET="$MACOSX_DEPLOYMENT_TARGET"\n',
144+
),
145+
)
146+
147+
for path, old, new in workflow_changes:
148+
data = path.read_text(encoding="utf-8")
149+
150+
if "make test-gm" in data:
151+
continue
152+
153+
if data.count(old) != 1:
154+
raise SystemExit(
155+
f"ERREUR: point d’insertion introuvable dans {path}"
156+
)
157+
158+
path.write_text(data.replace(old, new, 1), encoding="utf-8")
159+
160+
# ---------------------------------------------------------------------------
161+
# Documentation active.
162+
# ---------------------------------------------------------------------------
163+
164+
readme = Path("README_GAUSSIAN_FACTORING.md")
165+
data = readme.read_text(encoding="utf-8")
166+
167+
data = data.replace(
168+
"Gaussian-Mersenne P-1 and ECM — PrMers v99.89",
169+
"Gaussian-Mersenne P-1 and ECM — PrMers v99.90",
170+
1,
171+
)
172+
173+
readme.write_text(data, encoding="utf-8")
174+
PY
175+
176+
cat > RELEASE_V99.90_GAUSSIAN_MACOS_U64_FIX.md <<'EOF'
177+
# PrMers v99.90 — Gaussian macOS uint64/GMP portability fix
178+
179+
PrMers version:
180+
181+
```text
182+
4.20.79-alpha-v99.90-gaussian-macos-u64-fix
183+
bash <<'BASH'
184+
set -euo pipefail
185+
186+
REPO="$HOME/prmerscopy/PrMers"
187+
BRANCH="release-prmers-v99.90-final"
188+
189+
OLD_BUILD="4.20.78-alpha-v99.89-gaussian-worktodo-progress-json"
190+
NEW_BUILD="4.20.79-alpha-v99.90-gaussian-macos-u64-fix"
191+
192+
cd "$REPO"
193+
194+
# Sauvegarder un éventuel collage incomplet précédent.
195+
if test -n "$(git status --porcelain)"; then
196+
git stash push -u \
197+
-m "backup incomplete v99.90 correction $(date +%Y%m%d-%H%M%S)"
198+
fi
199+
200+
git switch main
201+
git pull --ff-only origin main
202+
git fetch --prune origin
203+
204+
test -z "$(git status --porcelain)"
205+
206+
if git ls-remote --exit-code --heads origin \
207+
"refs/heads/$BRANCH" >/dev/null 2>&1
208+
then
209+
echo "ERREUR: branche distante déjà présente : $BRANCH"
210+
exit 1
211+
fi
212+
213+
git branch -D "$BRANCH" 2>/dev/null || true
214+
git switch -c "$BRANCH"
215+
216+
python3 - "$OLD_BUILD" "$NEW_BUILD" <<'PY'
217+
from pathlib import Path
218+
import sys
219+
220+
old_build = sys.argv[1]
221+
new_build = sys.argv[2]
222+
223+
224+
def replace_once(filename: str, old: str, new: str) -> None:
225+
path = Path(filename)
226+
text = path.read_text(encoding="utf-8")
227+
count = text.count(old)
228+
229+
if count != 1:
230+
raise SystemExit(
231+
f"ERREUR: {filename}: attendu exactement 1 occurrence "
232+
f"de {old!r}, trouvé {count}"
233+
)
234+
235+
path.write_text(
236+
text.replace(old, new, 1),
237+
encoding="utf-8",
238+
)
239+
240+
241+
# Correction portable std::uint64_t vers GMP.
242+
replace_once(
243+
"src/modes/RunGaussianMersenneFactor.cpp",
244+
" mpz_class sigma = sigma64;",
245+
""" mpz_class sigma;
246+
mpz_import(
247+
sigma.get_mpz_t(),
248+
1,
249+
1,
250+
sizeof(sigma64),
251+
0,
252+
0,
253+
&sigma64);""",
254+
)
255+
256+
# Mise à jour de la version complète.
257+
for filename in (
258+
"include/core/Version.hpp",
259+
"tests/aevum_pow2_type4_source_test.py",
260+
"tests/gaussian_mersenne_factor_isolation_test.py",
261+
):
262+
replace_once(filename, old_build, new_build)
263+
264+
# Mise à jour de la version courte dans les JSON Gaussian.
265+
for filename in (
266+
"src/modes/RunGaussianMersenne.cpp",
267+
"src/modes/RunGaussianMersenneFactor.cpp",
268+
):
269+
replace_once(
270+
filename,
271+
'constexpr const char* GM_RELEASE = "v99.89";',
272+
'constexpr const char* GM_RELEASE = "v99.90";',
273+
)
274+
275+
# Ajouter un test empêchant le retour de la conversion ambiguë.
276+
test_path = Path("tests/gaussian_mersenne_factor_isolation_test.py")
277+
test = test_path.read_text(encoding="utf-8")
278+
279+
marker = f'assert "{new_build}" in version\n'
280+
checks = """
281+
# GMP C++ has no portable unsigned-long-long constructor on every ABI.
282+
assert "mpz_class sigma = sigma64;" not in source
283+
assert "mpz_import(" in source
284+
assert "sizeof(sigma64)" in source
285+
"""
286+
287+
if marker not in test:
288+
raise SystemExit("ERREUR: marqueur de version absent du test Gaussian")
289+
290+
if 'assert "mpz_class sigma = sigma64;" not in source' not in test:
291+
test = test.replace(marker, marker + checks, 1)
292+
293+
test_path.write_text(test, encoding="utf-8")
294+
295+
# Exécuter les tests Gaussian dans les CI Linux et macOS.
296+
workflow_changes = (
297+
(
298+
Path(".github/workflows/build_linux.yml"),
299+
" make test-aevum-host\n",
300+
" make test-gm\n"
301+
" make test-aevum-host\n",
302+
),
303+
(
304+
Path(".github/workflows/build_mac_os.yml"),
305+
' make test-aevum-host MACOSX_DEPLOYMENT_TARGET="$MACOSX_DEPLOYMENT_TARGET"\n',
306+
" make test-gm\n"
307+
' make test-aevum-host MACOSX_DEPLOYMENT_TARGET="$MACOSX_DEPLOYMENT_TARGET"\n',
308+
),
309+
)
310+
311+
for path, old, new in workflow_changes:
312+
data = path.read_text(encoding="utf-8")
313+
314+
if "make test-gm" in data:
315+
continue
316+
317+
if data.count(old) != 1:
318+
raise SystemExit(
319+
f"ERREUR: point d’insertion introuvable dans {path}"
320+
)
321+
322+
path.write_text(
323+
data.replace(old, new, 1),
324+
encoding="utf-8",
325+
)
326+
327+
# Mise à jour du titre de la documentation active.
328+
readme = Path("README_GAUSSIAN_FACTORING.md")
329+
data = readme.read_text(encoding="utf-8")
330+
331+
data = data.replace(
332+
"Gaussian-Mersenne P-1 and ECM — PrMers v99.89",
333+
"Gaussian-Mersenne P-1 and ECM — PrMers v99.90",
334+
1,
335+
)
336+
337+
readme.write_text(data, encoding="utf-8")
338+
PY
339+
340+
cat > RELEASE_V99.90_GAUSSIAN_MACOS_U64_FIX.md <<'EOF'
341+
# PrMers v99.90 — Gaussian macOS uint64/GMP portability fix
342+
343+
PrMers version:
344+
345+
4.20.79-alpha-v99.90-gaussian-macos-u64-fix
346+
347+
Aevum remains unchanged:
348+
349+
v0.3.78-workload-plan-policy-audit-fix
350+
351+
## Correction
352+
353+
The Gaussian-Mersenne ECM Suyama setup previously initialized an mpz_class
354+
directly from std::uint64_t.
355+
356+
On ABIs where std::uint64_t maps to unsigned long long, GMP C++ does not
357+
provide an unambiguous constructor for that type. This caused the macOS Intel
358+
release build to fail.
359+
360+
v99.90 imports the complete 64-bit value with mpz_import, without narrowing
361+
to unsigned long.
362+
363+
## Isolation
364+
365+
No Aevum source, Aevum kernel, Marin kernel, ordinary Mersenne PRP/LL, P-1 or
366+
ECM arithmetic has been modified.
367+
368+
## CI
369+
370+
The Gaussian mathematics, dispatch, JSON and worktodo tests are now explicitly
371+
executed by the Linux and macOS release workflows.

0 commit comments

Comments
 (0)