diff --git a/experiments/.gitignore b/experiments/.gitignore index d22b013..fcb94c2 100644 --- a/experiments/.gitignore +++ b/experiments/.gitignore @@ -7,3 +7,4 @@ batch/measurements/strong/* configs/measurements/strong/* *.dat *.db +eval/generated/* diff --git a/experiments/eval/Makefile b/experiments/eval/Makefile new file mode 100644 index 0000000..82a3db2 --- /dev/null +++ b/experiments/eval/Makefile @@ -0,0 +1,7 @@ +generate-batch-strong-cpu: + python scripts/substitute.py strong-batch.j2 < strong-cpu.json + +clean-logs: + rm logs/* + +.PHONY: generate-batch-strong-cpu clean-logs diff --git a/experiments/eval/generated/batch/.gitkeep b/experiments/eval/generated/batch/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/experiments/eval/generated/config/.gitkeep b/experiments/eval/generated/config/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/experiments/eval/load-modules b/experiments/eval/load-modules new file mode 100644 index 0000000..c387607 --- /dev/null +++ b/experiments/eval/load-modules @@ -0,0 +1 @@ +module load SciPy-Stack diff --git a/experiments/eval/logs/.gitkeep b/experiments/eval/logs/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/experiments/eval/scripts/generate-strong-cpu-configs.py b/experiments/eval/scripts/generate-strong-cpu-configs.py new file mode 100644 index 0000000..e9a2677 --- /dev/null +++ b/experiments/eval/scripts/generate-strong-cpu-configs.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python + +import copy +import json + +from pathlib import Path + +SIZE = [384, 384, 384] + +with (Path(__file__).parent.parent / "templates" / "strong-cpu.json").open(encoding="utf8") as f: + template = json.load(f) + +configs = [ + [ 4, 4, 3], + [ 4, 4, 6], + [ 4, 4, 12], + [ 4, 8, 12], + [ 8, 8, 12], + [ 8, 8, 24], + [ 8, 16, 24], + [ 16, 16, 24] +] + +out_path = Path(__file__).parent.parent / "generated" / "config" + +for c in configs: + nc = copy.deepcopy(template) + nc["Geometry"]["blockcount"] = c + nc["Geometry"]["blocksize"] = [bs // bc for bc, bs in zip(c, SIZE)] + + nc_out_path = out_path / f"strong-cpu-{c[0]:02}-{c[1]:02}-{c[2]:02}.json" + print(f"Dumping {(c[0] * c[1] * c[2]) // 48} to {nc_out_path}") + with nc_out_path.open("w", encoding="utf8") as f: + json.dump(nc, f) diff --git a/experiments/eval/scripts/substitute.py b/experiments/eval/scripts/substitute.py new file mode 100644 index 0000000..3ea80b8 --- /dev/null +++ b/experiments/eval/scripts/substitute.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python + +import jinja2 +import json +import sys + +from pathlib import Path + +data = json.load(sys.stdin) + +templates_env = jinja2.Environment( + loader=jinja2.FileSystemLoader(Path(__file__).parent.parent / "templates"), + autoescape=jinja2.select_autoescape() +) + +for possibly_incomplete_batch in data["batches"]: + batch = dict(list(data["common"].items()) + list(possibly_incomplete_batch.items())) + out_path = Path(__file__).parent.parent / "generated" / "batch" / batch["name"] + t = templates_env.get_template(sys.argv[1]) + print(f"Dumping to {out_path}") + t.stream(**batch).dump(str(out_path)) diff --git a/experiments/eval/strong-cpu.json b/experiments/eval/strong-cpu.json new file mode 100644 index 0000000..c1d41f1 --- /dev/null +++ b/experiments/eval/strong-cpu.json @@ -0,0 +1,61 @@ +{ + "common": { + "account": "cellsinsilico", + "partition": "batch", + "extra_sbatch_line": "", + "logfile_path": "/p/project/cellsinsilico/paulslustigebude/ma/experiments/eval/logs/%x-%A.%a", + "nastja_binary_path": "/p/project/cellsinsilico/paulslustigebude/nastja/build-nocuda/nastja", + "config_path": "/p/project/cellsinsilico/paulslustigebude/ma/experiments/eval/generated/config/${SLURM_JOB_NAME}.json", + "output_dir_path": "/p/scratch/cellsinsilico/paul/nastja-out/${SLURM_JOB_NAME}-${SLURM_JOB_ID}.${SLURM_ARRAY_TASK_ID}" + }, + "batches": [ + { + "name": "strong-cpu-04-04-03", + "nodes": 1, + "tasks": 48, + "time": "00:30:00" + }, + { + "name": "strong-cpu-04-04-06", + "nodes": 2, + "tasks": 96, + "time": "00:30:00" + }, + { + "name": "strong-cpu-04-04-12", + "nodes": 4, + "tasks": 192, + "time": "00:10:00" + }, + { + "name": "strong-cpu-04-08-12", + "nodes": 8, + "tasks": 384, + "time": "00:10:00" + }, + { + "name": "strong-cpu-08-08-12", + "nodes": 16, + "tasks": 768, + "time": "00:10:00" + }, + { + "name": "strong-cpu-08-08-24", + "nodes": 32, + "tasks": 1536, + "time": "00:10:00" + }, + { + "name": "strong-cpu-08-16-24", + "nodes": 64, + "tasks": 3072, + "time": "00:10:00" + }, + { + "name": "strong-cpu-16-16-24", + "nodes": 128, + "tasks": 6144, + "time": "00:10:00" + } + ] +} diff --git a/experiments/eval/templates/strong-batch.j2 b/experiments/eval/templates/strong-batch.j2 new file mode 100644 index 0000000..fc0a308 --- /dev/null +++ b/experiments/eval/templates/strong-batch.j2 @@ -0,0 +1,31 @@ +#!/usr/bin/env bash + +#SBATCH --job-name={{ name }} +#SBATCH --account={{ account }} +#SBATCH --partition={{ partition }} +#SBATCH --nodes={{ nodes }} +#SBATCH --ntasks={{ tasks }} +# Counted per node +{{ extra_sbatch_line }} +#SBATCH --time={{ time }} +#SBATCH --output={{ logfile_path }} +#SBATCH --error={{ logfile_path }} +#SBATCH --array=1-5 + +NASTJA_BINARY="{{ nastja_binary_path }}" +CONFIG_FILE="{{ config_path }}" +OUTPUT_DIR="{{ output_dir_path }}" +module load Stages/2024 GCC/12.3.0 ParaStationMPI/5.9.2-1 CMake/3.26.3 mold/1.11.0 jq/1.6 git Python + +echo "${NASTJA_BINARY_PATH}" +echo "${CONFIG_FILE}" +echo "${OUTPUT_DIR}" + +cat "${CONFIG_FILE}" + +mkdir -p "${OUTPUT_DIR}" + +srun "${NASTJA_BINARY}" \ + -c "${CONFIG_FILE}" \ + -o "${OUTPUT_DIR}" + diff --git a/experiments/eval/templates/strong-cpu.json b/experiments/eval/templates/strong-cpu.json new file mode 100644 index 0000000..59c35bd --- /dev/null +++ b/experiments/eval/templates/strong-cpu.json @@ -0,0 +1,258 @@ +{ + "Application": "Cells", + "CellsInSilico": { + "2D": false, + "adhesion": { + "matrix": [ + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 450.0], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 450.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 50.0] + ], + "polarityenabled": false + }, + "centerofmass": { + "steps": 1 + }, + "cleaner": { + "killdistance": 0, + "steps": 100 + }, + "contactinhibition": { + "enabled": false + }, + "division": { + "condition": [ + "", + "", + "", + "", + "", + "", + "", + "", + "", + "( volume >= 0.9 * volume0 ) & ( rnd() <= 0.00001 ) & generation < 1" + ], + "enabled": true, + "halveSignals": false + }, + "dynamicecm": { + "alpha": 2.0, + "beta": 0.5, + "c": 4.0, + "deltat": 0.10000000149011612, + "ecmCellID": 0, + "enabled": true, + "eta": 0.25, + "k0": 0.10000000149011612, + "k1": 0.10000000149011612, + "lambda": 10.0, + "phi": 1.0, + "pushSteps": 10, + "pushWeight": 0.5, + "stepsPerMcs": 100 + }, + "ecmdegradation": { + "enabled": false + }, + "energyfunctions": [ + "Volume00", + "Surface01", + "Motility00", + "Adhesion01", + "DynamicECM00" + ], + "liquid": 6, + "logcellproperties": { + "enabled": false + }, + "orientation": { + "enabled": true, + "motility": "persistentRandomWalk", + "motilityamount": [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + "numRandomNumbers": 5, + "persistenceMagnitude": 0.0, + "persistentDecay": 0.8, + "recalculationtime": 200 + }, + "polarity": { + "enabled": false + }, + "signaling": { + "constant": false, + "enabled": false + }, + "surface": { + "default": { + "storage": "const", + "value": 400.0 + }, + "lambda": [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 5.625, + 5.625, + 1.0 + ], + "sizechange": [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.05, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ] + }, + "temperature": 50.0, + "visitor": { + "checkerboard": "01", + "stepwidth": 10 + }, + "volume": { + "default": { + "storage": "const", + "value": 500.0 + }, + "lambda": [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 7.5, + 7.5, + 7.5 + ], + "sizechange": [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.05, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ] + } + }, + "DefineFunctions": [ + "r_angle()=360*rnd()", + "r_size()=400*rnd()" + ], + "Filling": { + "cells": [ + { + "box": [ + [ + 0, + 0, + 0 + ], + [ + 384, + 384, + 384 + ] + ], + "celltype": 0, + "component": 0, + "pattern": "const", + "seed": 0, + "shape": "cube", + "value": 0 + }, + { + "box": [ + [117, 117, 177], + [267, 267, 267] + ], + "celltype": 9, + "center": [192, 192, 192], + "component": 0, + "count": 5500, + "pattern": "voronoi", + "radius": 75, + "seed": 758960, + "shape": "sphere", + "value": 8 + } + ], + "initialoutput": false, + "randomseed": 758959 + }, + "Geometry": { + "blockcount": [ + 4, + 4, + 3 + ], + "blockdefault": "fill", + "blocksize": [ + 96, + 96, + 128 + ], + "blocktype": [ + [ + [ + 1 + ] + ] + ] + }, + "Settings": { + "deltat": 1.0, + "deltax": 1.0, + "handleFPE": "signal", + "logger": { + "group": 0, + "steps": 100 + }, + "randomseed": 42, + "statusoutput": 1, + "timestepguard": 1, + "timesteps": 5 + } +}