# Scalable manifest for the Demeter LULCC running example
# ---------------------------------------------------------
# Demeter is the land-use / land-cover disaggregation model from JGCRI
# (https://github.com/JGCRI/demeter). When a single GCAM run produces
# projected land allocations for multiple scenarios, Demeter must downscale
# each scenario independently. That fan-out is the canonical workload
# Scalable was designed for.
#
# This manifest is the single source of truth referenced by every tutorial
# and notebook in the v2.0.0 series. See:
#   - plans/demeter_running_example.md (contract)
#   - docs/examples/workflow_demeter.py (workflow that consumes this manifest)
#   - docs/tutorials/demeter_setup.rst (one-time setup instructions)
#
# Pipeline (driven by workflow_demeter.py):
#   prepare_demeter_config -> run_demeter_scenario (×N) -> aggregate_demeter_outputs

version: 1
project:
  name: demeter-lulcc
  default_storage: ./outputs

targets:
  # --- Local laptop / CI -------------------------------------------------
  # ``processes: false`` keeps Dask in-thread which avoids the Nanny
  # spawn startup cost (and macOS / Python 3.13 fork edge cases). Tutorials
  # that demonstrate process isolation flip this to ``true``.
  local:
    provider: local
    max_workers: 4
    threads_per_worker: 1
    processes: false
    containers: none

  # --- HPC (Slurm) -------------------------------------------------------
  hpc:
    provider: slurm
    queue: short
    account: GCIMS
    walltime: "02:00:00"
    interface: ib0
    overlay: hpc-large

  # --- Kubernetes (e.g. GKE / EKS / on-prem) -----------------------------
  k8s:
    provider: kubernetes
    namespace: demeter-prod
    image: ghcr.io/jgcri/demeter:2.0.1
    adaptive:
      minimum: 2
      maximum: 20

  # --- AWS Fargate -------------------------------------------------------
  aws:
    provider: aws
    region: us-east-1
    cluster_type: fargate
    instance_type: m5.xlarge
    worker_cpu: 4096
    worker_mem: 16384
    image: ${ECR_DEMETER_IMAGE:-123456789.dkr.ecr.us-east-1.amazonaws.com/demeter:2.0.1}
    execution_role_arn: arn:aws:iam::123456789:role/ecsTaskExecutionRole
    task_role_arn: arn:aws:iam::123456789:role/ecsTaskRole
    adaptive:
      minimum: 1
      maximum: 10

components:
  # Lightweight: build per-scenario .ini files from a base template.
  preprocess:
    cpus: 1
    memory: 2G
    tags: [lulcc, config]

  # Heavy: runs `demeter.run_model(config_file=...)` for one scenario.
  # Image comes from capabilities/demeter/Dockerfile.scalable. The mount
  # for ./demeter_data is added per-target via the overlays below — local
  # runs see the host filesystem directly so no mount is needed.
  demeter:
    image: ghcr.io/jgcri/demeter:2.0.1
    runtime: apptainer
    cpus: 4
    memory: 16G
    env:
      DEMETER_DATA: /data
    tags: [lulcc, downscaling, gcam]

  # Aggregation: merges per-scenario NetCDF/CSV outputs into summary tables.
  postprocess:
    cpus: 2
    memory: 8G
    tags: [lulcc, aggregation]

tasks:
  prepare_demeter_config:
    component: preprocess
    cache: true
  run_demeter_scenario:
    component: demeter
    cache: true
    outputs:
      output_dir: dir
  aggregate_demeter_outputs:
    component: postprocess
    cache: true

# Overlays let one base manifest serve laptops, HPC, and cloud without
# duplicating the components block. The HPC overlay bumps memory for the
# full GCAM ensemble; the K8s overlay handles fine-resolution runs.
overlays:
  # Bind-mount the host's demeter_data into the container; only applied to
  # targets that actually use a container runtime (hpc / k8s / aws).
  containerized:
    components:
      demeter:
        mounts:
          ${DEMETER_DATA_HOST:-/shared/demeter_data}: /data

  hpc-large:
    components:
      demeter:
        cpus: 16
        memory: 64G
        mounts:
          ${DEMETER_DATA_HOST:-/shared/demeter_data}: /data
      postprocess:
        cpus: 4
        memory: 16G

  k8s-fine-resolution:
    components:
      demeter:
        memory: 64G
        mounts:
          ${DEMETER_DATA_HOST:-/shared/demeter_data}: /data

  dev:
    components:
      demeter:
        cpus: 1
        memory: 4G
