Skip to content

Add late-time material relational development workflow #1

Add late-time material relational development workflow

Add late-time material relational development workflow #1

name: Cosmology late-time material relational development
on:
workflow_dispatch:
push:
branches:
- dark-sector-stability-architecture
paths:
- '.github/workflows/cosmology-late-time-material-relational-development.yml'
permissions:
contents: write
concurrency:
group: cosmology-late-time-material-relational-development
cancel-in-progress: true
jobs:
development:
runs-on: ubuntu-latest
timeout-minutes: 75
env:
GEVOLUTION_SHA: 0cca42e51a824002ae4fb602cbd79d671e8ffe60
LATFIELD2_SHA: 2d8c737ab6adc965a1d2718c209f5085af27b09c
TEMPLATE_BLOB: d4de9a5400ef58f6a0181fbe61f18056b233a425
BOXSIZE: 64.0
steps:
- name: Check out repository
uses: actions/checkout@v4
with:
ref: dark-sector-stability-architecture
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y build-essential openmpi-bin libopenmpi-dev libfftw3-dev libgsl-dev libhdf5-dev
python -m pip install --upgrade pip
python -m pip install numpy h5py
- name: Verify frozen APQ adjudication
run: |
git log -1 --format=%H -- dark_sector_architecture/LATE_TIME_MATERIAL_RELATIONAL_APQ2_ADJUDICATION_v0.1.md \
| tee material_relational_apq_commit.txt
- name: Fetch pinned sources and template
run: |
git clone https://github.com/gevolution-code/gevolution-1.3.git gevolution
git -C gevolution checkout "$GEVOLUTION_SHA"
git clone https://gitlab.uzh.ch/julian.adamek/LATfield2.git LATfield2
git -C LATfield2 checkout "$LATFIELD2_SHA"
curl -L --fail --silent --show-error \
https://raw.githubusercontent.com/gevolution-code/gevolution-1.2/df8a930732aae1bafa32fd839ee70728bb10773a/sc1_crystal.dat \
-o gevolution/material_relational_template.dat
test "$(git hash-object gevolution/material_relational_template.dat)" = "$TEMPLATE_BLOB"
- name: Patch dynamic hij output and full-precision snapshot metadata
run: |
python - <<'PY'
from pathlib import Path
path=Path('gevolution/main.cpp')
text=path.read_text()
marker=(
'\t\t// snapshot output\n'
'\t\tif (snapcount < sim.num_snapshot && '
'1. / a < sim.z_snapshot[snapcount] + 1.)\n'
)
if marker not in text:
raise SystemExit('snapshot marker missing')
replacement=(
'\t\t// snapshot output\n'
'#ifdef TENSOR_EVOLUTION\n'
'\t\tif ((sim.out_snapshot & MASK_HIJ) &&\n'
'\t\t snapcount < sim.num_snapshot &&\n'
'\t\t 1. / a < sim.z_snapshot[snapcount] + 1.)\n'
'\t\t{\n'
'\t\t\tplan_hij.execute(FFT_BACKWARD);\n'
'\t\t\tSij.updateHalo();\n'
'\t\t\tdone_hij = 1;\n'
'\t\t}\n'
'#endif\n'
'\t\tif (snapcount < sim.num_snapshot && '
'1. / a < sim.z_snapshot[snapcount] + 1.)\n'
'\t\t{\n'
'\t\t\tchar material_meta[256];\n'
'\t\t\tsprintf(material_meta, '
'"MATERIAL_REL_META index=%d cycle=%d a=%.17g z=%.17g '
'tau_over_boxsize=%.17g", snapcount, cycle, a, (1./a)-1., tau);\n'
'\t\t\tCOUT << material_meta << endl;\n'
'\t\t}\n'
'\t\tif (snapcount < sim.num_snapshot && '
'1. / a < sim.z_snapshot[snapcount] + 1.)\n'
)
path.write_text(text.replace(marker,replacement,1))
PY
- name: Compile gevolution
working-directory: gevolution
run: |
make clean
make -j2 \
INCLUDE="-I../LATfield2 -I/usr/include/hdf5/serial" \
LIB="-lfftw3 -lm -L/usr/lib/x86_64-linux-gnu/hdf5/serial -lhdf5 -lgsl -lgslcblas" \
DGEVOLUTION="-DPHINONLINEAR -DBENCHMARK -DVELOCITY -DTENSOR_EVOLUTION"
- name: Build frozen N64 fifteen-snapshot settings
run: |
python - <<'PY'
from pathlib import Path
import json
base=Path('dark_sector_architecture/qualification/gevolution_modal_pilot.ini').read_text()
centers=[1/3,1/2,2/3]
offsets=[0.995,0.9975,1.0,1.0025,1.005]
scale_factors=[c*f for c in centers for f in offsets]
if any(b <= a for a,b in zip(scale_factors,scale_factors[1:])):
raise SystemExit('scale factors not globally increasing')
redshifts=[1/a-1 for a in scale_factors]
rtext=', '.join(f'{z:.12f}' for z in redshifts)
replacements={
'template file = pilot_template.dat':'template file = material_relational_template.dat',
'tiling factor = 2':'tiling factor = 16',
'Ngrid = 8':'Ngrid = 64',
'time step limit = 0.04':'time step limit = 0.0005',
'output path = ../pilot_output/':'output path = ../material_relational_output/',
'generic file base = modalpilot':'generic file base = material_relational',
'snapshot file base = modalpilot_snap':'snapshot file base = material_relational_snap',
'snapshot redshifts = 99':f'snapshot redshifts = {rtext}',
'snapshot outputs = phi, B, chi, hij, v':'snapshot outputs = phi, B, chi, hij, v, particles',
'Pk file base = modalpilot_pk':'Pk file base = material_relational_pk',
'Pk redshifts = 99':f'Pk redshifts = {redshifts[7]:.12f}',
}
text=base
for old,new in replacements.items():
if old not in text:
raise SystemExit(f'missing settings token: {old}')
text=text.replace(old,new,1)
Path('gevolution/material_relational.ini').write_text(text)
Path('material_relational_requested.json').write_text(
json.dumps({
'grid':64,'seed':424242,'boxsize_mpc_over_h':64.0,
'scale_factors':scale_factors,'requested_redshifts':redshifts,
'central_indices':[2,7,12],'time_step_limit':0.0005
},indent=2,sort_keys=True)+'\n'
)
PY
- name: Run development trajectory
run: |
set -o pipefail
rm -rf material_relational_output
mkdir -p material_relational_output
cd gevolution
mpirun --oversubscribe -np 4 ./gevolution -n 2 -m 2 -s material_relational.ini \
| tee ../material_relational.log
- name: Parse exact metadata and verify outputs
run: |
python - <<'PY'
import json,re
from pathlib import Path
req=json.loads(Path('material_relational_requested.json').read_text())
text=Path('material_relational.log').read_text()
pattern=re.compile(
r'MATERIAL_REL_META index=([0-9]+) cycle=([0-9]+) '
r'a=([0-9eE+.-]+) z=([0-9eE+.-]+) tau_over_boxsize=([0-9eE+.-]+)'
)
matches=pattern.findall(text)
if len(matches)!=15:
raise SystemExit(f'expected 15 snapshot metadata lines, got {len(matches)}')
root=Path('material_relational_output')
snaps=[]
for j,(idx,cycle,a,z,tau) in enumerate(matches):
if int(idx)!=j:
raise SystemExit('snapshot index mismatch')
for token in ('phi','chi','B','hij','v','cdm'):
files=list(root.glob(f'*snap{j:03d}_{token}.h5'))
if len(files)!=1:
raise SystemExit(f'missing snap{j:03d}_{token}: {files}')
snaps.append({
'index':j,
'requested_redshift':req['requested_redshifts'][j],
'actual_scale_factor':float(a),
'actual_redshift':float(z),
'cycle':int(cycle),
'tau_over_boxsize':float(tau),
})
taus=[x['tau_over_boxsize'] for x in snaps]
if any(b<=a for a,b in zip(taus,taus[1:])):
raise SystemExit('conformal times not strictly increasing')
for center in req['central_indices']:
cycles=[snaps[i]['cycle'] for i in range(center-2,center+3)]
if len(set(cycles))!=5:
raise SystemExit(f'central cluster {center} lacks distinct cycles: {cycles}')
meta={
'protocol':'P0-Q_LATE_TIME_MATERIAL_RELATIONAL_MEMBER',
'grid':64,'seed':424242,'boxsize_mpc_over_h':64.0,
'gevolution_sha':'0cca42e51a824002ae4fb602cbd79d671e8ffe60',
'latfield2_sha':'2d8c737ab6adc965a1d2718c209f5085af27b09c',
'snapshots':snaps,
}
out=Path('dark_sector_architecture/qualification/results')
out.mkdir(parents=True,exist_ok=True)
(out/'late_time_material_relational_metadata.json').write_text(
json.dumps(meta,indent=2,sort_keys=True)+'\n'
)
PY
- name: Run frozen development analysis
run: |
python dark_sector_architecture/qualification/run_late_time_material_relational_development.py \
--snapshot-dir material_relational_output \
--metadata dark_sector_architecture/qualification/results/late_time_material_relational_metadata.json \
--output dark_sector_architecture/qualification/results/late_time_material_relational_development.json
- name: Add frozen provenance
run: |
python - <<'PY'
import json
from pathlib import Path
p=Path('dark_sector_architecture/qualification/results/late_time_material_relational_development.json')
d=json.loads(p.read_text())
d['frozen_apq_adjudication_commit']=Path('material_relational_apq_commit.txt').read_text().strip()
d['workflow_head']='${{ github.sha }}'
p.write_text(json.dumps(d,indent=2,sort_keys=True)+'\n')
print(json.dumps({
'development_outcome':d['development_outcome'],
'delta_rel':d['primary_z2_to_z1']['delta_rel'],
'shift_q95':d['primary_z2_to_z1']['shift_null']['delta_rel_q95'],
'sse_persistence':d['primary_z2_to_z1']['sse_persistence'],
'sse_b0':d['primary_z2_to_z1']['sse_b0'],
'sse_b1':d['primary_z2_to_z1']['sse_b1']
},sort_keys=True))
PY
- name: Upload compact development artifact
uses: actions/upload-artifact@v4
with:
name: cosmology-late-time-material-relational-development
path: |
material_relational_apq_commit.txt
material_relational_requested.json
material_relational.log
gevolution/material_relational.ini
dark_sector_architecture/qualification/results/late_time_material_relational_metadata.json
dark_sector_architecture/qualification/results/late_time_material_relational_development.json
if-no-files-found: error
- name: Persist development summaries
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add \
dark_sector_architecture/qualification/results/late_time_material_relational_metadata.json \
dark_sector_architecture/qualification/results/late_time_material_relational_development.json
if git diff --cached --quiet; then exit 0; fi
git commit -m "Persist late-time material relational development"
for attempt in 1 2 3 4 5; do
git fetch origin dark-sector-stability-architecture
git rebase origin/dark-sector-stability-architecture
if git push origin HEAD:dark-sector-stability-architecture; then exit 0; fi
sleep 2
done
exit 1