Skip to content

Commit e930b22

Browse files
committed
phase 5 shell script added
1 parent e85702a commit e930b22

4 files changed

Lines changed: 163 additions & 25 deletions

File tree

hpc/run_phase1.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
#!/bin/bash
22
#SBATCH --job-name=pp_phase1
3-
#SBATCH --partition=rome
3+
#SBATCH --partition=genoa
44
#SBATCH --nodes=1
55
#SBATCH --ntasks=1
6-
#SBATCH --cpus-per-task=32
6+
#SBATCH --cpus-per-task=128
77
#SBATCH --time=04:00:00
88
#SBATCH --mem=16G
99
#SBATCH --output=pp_phase1_%j.out

hpc/run_phase6.sh

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
#!/bin/bash
2+
#SBATCH --job-name=pp_phase6
3+
#SBATCH --partition=genoa
4+
#SBATCH --nodes=1
5+
#SBATCH --ntasks=1
6+
#SBATCH --cpus-per-task=128
7+
#SBATCH --time=08:00:00
8+
#SBATCH --mem=0
9+
#SBATCH --output=pp_phase6_%j.out
10+
#SBATCH --error=pp_phase6_%j.err
11+
12+
# =============================================================================
13+
# PP Hydra Effect - Phase 6: Directed Hunting 4D Sweep
14+
# =============================================================================
15+
#
16+
# PHASE 6: Full 4D parameter sweep with directed hunting enabled
17+
# - Same structure as Phase 4 but with directed_hunting=True
18+
# - 11^4 × 10 reps = 146,410 simulations
19+
# - Grid size: 250
20+
# - Collects time series for comparison with Phase 4
21+
# - Estimated runtime: ~4-6 hours on 128 cores
22+
# - Memory: mem=0 (use all available node memory)
23+
#
24+
# PURPOSE: Test if Hydra effect and SOC persist under directed hunting
25+
#
26+
# SUBMIT: sbatch run_phase6.sh
27+
# MONITOR: squeue -u $USER
28+
# CANCEL: scancel <job_id>
29+
#
30+
# =============================================================================
31+
32+
echo "========================================"
33+
echo "PP Hydra Effect - Phase 6"
34+
echo "========================================"
35+
echo "Job ID: $SLURM_JOB_ID"
36+
echo "Node: $(hostname)"
37+
echo "CPUs: $SLURM_CPUS_PER_TASK"
38+
echo "Start: $(date)"
39+
echo "Working dir: $(pwd)"
40+
echo "========================================"
41+
42+
# -----------------------------------------------------------------------------
43+
# Environment Setup
44+
# -----------------------------------------------------------------------------
45+
46+
source ~/snellius_venv/bin/activate
47+
48+
# Prevent numpy/scipy from spawning extra threads (joblib handles parallelism)
49+
export OMP_NUM_THREADS=1
50+
export OPENBLAS_NUM_THREADS=1
51+
export MKL_NUM_THREADS=1
52+
export NUMEXPR_NUM_THREADS=1
53+
54+
# -----------------------------------------------------------------------------
55+
# Run Phase 6
56+
# -----------------------------------------------------------------------------
57+
58+
OUTPUT_DIR="results/phase6_${SLURM_JOB_ID}"
59+
mkdir -p $OUTPUT_DIR
60+
61+
echo ""
62+
echo "Output directory: $OUTPUT_DIR"
63+
echo ""
64+
65+
# Dry run first to verify setup
66+
echo "Dry run check:"
67+
python3 -u scripts/experiments.py \
68+
--phase 6 \
69+
--output $OUTPUT_DIR \
70+
--cores $SLURM_CPUS_PER_TASK \
71+
--dry-run
72+
73+
echo ""
74+
echo "Starting Phase 6..."
75+
echo ""
76+
77+
# Run phase 6
78+
python3 -u scripts/experiments.py \
79+
--phase 6 \
80+
--output $OUTPUT_DIR \
81+
--cores $SLURM_CPUS_PER_TASK
82+
83+
# -----------------------------------------------------------------------------
84+
# Completion
85+
# -----------------------------------------------------------------------------
86+
87+
echo ""
88+
echo "========================================"
89+
echo "Phase 6 Complete"
90+
echo "========================================"
91+
echo "End time: $(date)"
92+
echo "Results in: $OUTPUT_DIR/"
93+
echo ""
94+
echo "Output files:"
95+
ls -lh $OUTPUT_DIR/
96+
echo ""
97+
echo "Next steps:"
98+
echo " 1. Download phase6_results.jsonl"
99+
echo " 2. Compare with Phase 4 results (random hunting baseline)"
100+
echo " 3. Analyze if Hydra effect persists under directed hunting"
101+
echo " 4. Compare critical point locations between Phase 4 and Phase 6"
102+
echo " 5. Check for differences in SOC signatures"
103+
echo "========================================"

models/config.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -192,13 +192,13 @@ def estimate_runtime(self, n_cores: int = 32) -> str:
192192
grid_size=1000,
193193
n_prey_death=20,
194194
prey_birth=0.2,
195-
prey_death_range=(0.00, 0.2),
195+
prey_death_range=(0.09, 0.12),
196196
predator_birth=0.8,
197197
predator_death=0.05,
198198
n_replicates=30,
199-
warmup_steps=1000,
199+
warmup_steps=4000,
200200
measurement_steps=1000,
201-
collect_pcf=True,
201+
collect_pcf=False,
202202
pcf_sample_rate=0.2,
203203
save_timeseries=False,
204204
directed_hunting=False,

scripts/experiments.py

Lines changed: 55 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -646,52 +646,87 @@ def run_phase5(cfg: Config, output_dir: Path, logger: logging.Logger) -> List[Di
646646
return all_results
647647

648648

649-
def run_phase6(cfg: Config, output_dir: Path, logger: logging.Logger) -> List[Dict]:
649+
650+
def run_phase4(cfg: Config, output_dir: Path, logger: logging.Logger) -> List[Dict]:
650651
"""
651-
Phase 6: Model extensions.
652-
- Compare directed vs random hunting
653-
- Check if Hydra effect and SOC persist
652+
Phase 4: Global Sensitivity Analysis.
653+
Vary: prey_birth, prey_death, predator_birth, predator_death
654+
Range: 0-1 (11 values each)
655+
Reps: 10
656+
Grid size: 250
654657
"""
655658
from joblib import Parallel, delayed
659+
import itertools
656660

657661
warmup_numba_kernels(cfg.grid_size, directed_hunting=cfg.directed_hunting)
658662

659-
prey_deaths = cfg.get_prey_deaths()
663+
# Define the global sweep values
664+
sweep_values = np.linspace(0.0, 1.0, 11)
665+
666+
# Logging
667+
logger.info(f"Phase 4: Full 4D Parameter Sweep")
668+
logger.info(f" Parameters: prey_birth, prey_death, pred_birth, pred_death")
669+
logger.info(f" Range: 0.0 to 1.0 (11 steps)")
670+
logger.info(f" Grid Size: {cfg.grid_size}")
671+
logger.info(f" Replicates: {cfg.n_replicates}")
672+
673+
param_grid = itertools.product(sweep_values, repeat=4)
674+
660675
jobs = []
661-
for pd in prey_deaths:
676+
677+
for pb, pd, pred_b, pred_d in param_grid:
662678
for rep in range(cfg.n_replicates):
663-
params = {"pd": pd}
664-
seed = generate_unique_seed(params, rep)
665-
jobs.append((cfg.prey_birth, pd, cfg.predator_birth, cfg.predator_death,
666-
cfg.grid_size, seed, cfg, False))
679+
# Create params dict for unique seed generation
680+
params_id = {
681+
"pb": pb,
682+
"pd": pd,
683+
"pred_b": pred_b,
684+
"pred_d": pred_d,
685+
"rep": rep
686+
}
687+
seed = generate_unique_seed(params_id, rep)
667688

668-
logger.info(f"Phase 6: {len(jobs):,} simulations (directed hunting)")
669-
logger.info(f" Grid: {cfg.n_prey_death} prey_death values × {cfg.n_replicates} reps (prey_birth={cfg.prey_birth})")
670-
671-
output_jsonl = output_dir / "phase6_results.jsonl"
689+
# Job Signature:
690+
# (prey_birth, prey_death, predator_birth, predator_death, grid_size, seed, cfg, with_evolution)
691+
jobs.append((
692+
pb,
693+
pd,
694+
pred_b,
695+
pred_d,
696+
cfg.grid_size,
697+
seed,
698+
cfg,
699+
False
700+
))
701+
702+
logger.info(f" Total simulations: {len(jobs):,}")
703+
output_jsonl = output_dir / "phase4_results.jsonl"
672704
all_results = []
673705

674706
with open(output_jsonl, "w", encoding="utf-8") as f:
675707
executor = Parallel(n_jobs=cfg.n_jobs, return_as="generator")
676708
tasks = (delayed(run_single_simulation)(*job) for job in jobs)
677709

678-
for result in tqdm(executor(tasks), total=len(jobs), desc="Phase 6"):
710+
# tqdm shows progress for the massive job list
711+
for result in tqdm(executor(tasks), total=len(jobs), desc="Phase 4 (4D Sweep)"):
679712
f.write(json.dumps(result, default=str) + "\n")
680713
f.flush()
681714
all_results.append(result)
682715

683-
# Save metadata
716+
# 4. Save Metadata
684717
meta = {
685-
"phase": 6,
686-
"description": "Parameter sweep for critical point with directed hunting",
718+
"phase": 4,
719+
"description": "Global 4D Sensitivity Analysis",
720+
"sweep_values": sweep_values.tolist(),
721+
"parameters_varied": ["prey_birth", "prey_death", "predator_birth", "predator_death"],
687722
"n_sims": len(all_results),
688723
"timestamp": time.strftime("%Y-%m-%d %H:%M:%S"),
689724
"config": asdict(cfg),
690725
}
691-
with open(output_dir / "phase6_metadata.json", "w") as f:
726+
with open(output_dir / "phase4_metadata.json", "w") as f:
692727
json.dump(meta, f, indent=2, default=str)
693728

694-
logger.info(f"Phase 6 complete. Results: {output_jsonl}")
729+
logger.info(f"Phase 4 complete. Results: {output_jsonl}")
695730
return all_results
696731
# =============================================================================
697732
# Main:

0 commit comments

Comments
 (0)