diff --git a/.devcontainer/postCreateCommand.sh b/.devcontainer/postCreateCommand.sh index 98c2244..d1cbc25 100644 --- a/.devcontainer/postCreateCommand.sh +++ b/.devcontainer/postCreateCommand.sh @@ -1,9 +1,12 @@ #!/bin/bash CODE_TEMPLATE=/usr/local/src/code_template -CODE=/workspaces/code +INFRA=/workspaces/code +CODE=/workspaces -ln -s $CODE_TEMPLATE/.venv $CODE/.venv +# .venv is infra-private; external and libneo are workspace-shared +ln -s $CODE_TEMPLATE/.venv $INFRA/.venv +mkdir -p $CODE/external ln -s $CODE_TEMPLATE/external/fgsl-1.6.0 $CODE/external/fgsl-1.6.0 cp -r $CODE_TEMPLATE/libneo $CODE/libneo diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index 6154a9d..0000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,125 +0,0 @@ -# This is a basic workflow to help you get started with Actions - -name: CI - -# Controls when the workflow will run -on: - # Triggers the workflow on push or pull request events but only for the "main" branch - push: - branches: [ "main" ] - pull_request: - branches: [ "main" ] - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -env: - GIT_HTTPS: "true" - CI_MERGE_REQUEST_SOURCE_BRANCH_NAME: "${{ github.head_ref }}" - -jobs: - code: - name: Build and test - runs-on: ubuntu-24.04 - - steps: - - name: Install dependencies - run: | - sudo apt-get update -y && sudo apt-get install -y -q --no-install-recommends \ - apt-transport-https \ - build-essential \ - ca-certificates \ - curl \ - libssl-dev \ - openssh-client \ - rsync \ - wget \ - git \ - gfortran \ - ninja-build \ - cmake \ - python3 \ - python3-dev \ - python3-pip \ - python3-venv - - sudo apt-get install -y -q --no-install-recommends \ - python3-tk \ - idle3 \ - findent \ - expect \ - environment-modules - - sudo apt-get install -y -q --no-install-recommends \ - pkg-config \ - libsuitesparse-dev \ - libopenblas-dev \ - libsuperlu-dev \ - libhdf5-dev \ - libhdf5-openmpi-dev \ - libnetcdf-dev \ - libnetcdff-dev \ - libfftw3-dev \ - libgsl-dev \ - libopenmpi-dev \ - libscalapack-openmpi-dev \ - libpcre3-dev \ - libreadline-dev \ - h5utils \ - hdf5-tools \ - netcdf-bin \ - libmetis-dev \ - libboost-all-dev - - - name: Download Release # TODO: make this dynamic - run: | - wget https://github.com/itpplasma/code/releases/download/v2025.01.02/code-v2025.01.02.tar.gz -O /tmp/code.tar.gz - - - name: Extract tarball - run: | - tar -xzvf /tmp/code.tar.gz - - - name: NEO-2 - run: | - source activate.sh - clone_github NEO-2 - cd NEO-2 - $CODE/scripts/checkout_branch.sh $CODE_BRANCH - make - - - name: NEO-RT - run: | - source activate.sh - clone_github NEO-RT - cd NEO-RT - $CODE/scripts/checkout_branch.sh $CODE_BRANCH - make - - - name: SIMPLE - run: | - source activate.sh - clone_github SIMPLE - cd SIMPLE - $CODE/scripts/checkout_branch.sh $CODE_BRANCH - make - - - - name: GORILLA - run: | - source activate.sh - clone_github GORILLA - cd GORILLA - $CODE/scripts/checkout_branch.sh $CODE_BRANCH - make - - - name: MEPHIT - run: | - source activate.sh - clone_github MEPHIT - source /etc/profile.d/modules.sh - module use -a $CODE/modules - module load mephit - cd MEPHIT - $CODE/scripts/checkout_branch.sh $CODE_BRANCH - make - pip install -e . diff --git a/.github/workflows/setup.yml b/.github/workflows/setup.yml index b7c7ce8..b51d944 100644 --- a/.github/workflows/setup.yml +++ b/.github/workflows/setup.yml @@ -76,17 +76,27 @@ jobs: libmetis-dev \ libboost-all-dev + # TODO(infra-relocation): this workflow runs on version tags only and is + # NOT exercised by PR CI. After the infra relocation, setup.sh builds the + # shared deps into $CODE/external (the workspace, parent of this checkout), + # so the steps below must build there and bundle external/ into the release + # tarball alongside the infra content. Validate on a real tag before + # cutting the next release; main.yml still consumes the pinned old release. - name: Setup run: | set -e source scripts/setup.sh - pushd external - ../scripts/setup/mfem.sh + CODE="$(cd .. && pwd)" + pushd "$CODE/external" + "$GITHUB_WORKSPACE/scripts/setup/mfem.sh" popd - name: Build tarball run: | set -e + CODE="$(cd .. && pwd)" + # flat release archive: infra content + the shared external/ at root + cp -r "$CODE/external" ./external tar -czf /tmp/code.tar.gz . - name: Create GitHub Release diff --git a/README.md b/README.md index 4669b05..854b36a 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,24 @@ CODE is based around our standard Debian bookworm system at ITPcp and provides - Container definitions - VSCode settings +## Layout + +This repository is the `infra` directory of a workspace. The workspace is the +environment variable `$CODE`; this repository is `$INFRA`, equal to +`$CODE/infra`. The code checkouts sit in the workspace next to `infra`: + + $CODE/ + infra/ this repository (activation, setup scripts, modules, .venv) + external/ prebuilt third-party libs, shared by all codes + libneo/ code checkout + SIMPLE/ code checkout + ... + +Activation exports both. `$INFRA` holds the infra-private paths (`scripts`, +`.venv`, `modules`). `$CODE` is the workspace root, so the codes resolve their +dependencies as `$CODE/` and read prebuilt libraries from +`$CODE/external`. + ## Getting Started If you haven't done so earlier, set up your SSH keys in `~/.ssh` via `ssh-keygen` @@ -35,30 +53,31 @@ to install Debian Linux via WSL2. Then follow the Linux instructions. ### Initial setup -Clone the repository to your working copy, at the institute this is +Clone this repository into an `infra` directory inside your workspace. At the +institute the workspace is `/proj/plasma/CODE/`: - git clone git@github.com:itpplasma/code /proj/plasma/CODE/ + git clone git@github.com:itpplasma/code /proj/plasma/CODE//infra -Then open the directory in VS Code with +Open the workspace in VS Code with - code code + code /proj/plasma/CODE/ When asked to initialize the devcontainer, remove the message. Run the setup script manually with - scripts/setup.sh + infra/scripts/setup.sh -The setup will install external dependencies and create -a Python virtual environment in the hidden `.venv` directory. +The setup installs external dependencies and creates the Python virtual +environment in `infra/.venv`. Finally, activate the environment with - source activate.sh + source infra/activate.sh To use this environment as a standard, put the activation script into bashrc with - echo "source $PWD/activate.sh" >> ~/.bashrc + echo "source /proj/plasma/CODE//infra/activate.sh" >> ~/.bashrc ## External codes diff --git a/SIMPLE b/SIMPLE deleted file mode 160000 index 8483ed8..0000000 --- a/SIMPLE +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 8483ed8890ac5c69d2aa7565ceb6fb4b65887a47 diff --git a/activate.fish b/activate.fish index c8a0056..956ad2d 100644 --- a/activate.fish +++ b/activate.fish @@ -3,21 +3,23 @@ # Fish shell activation script # Usage: source activate.fish -# Get the directory containing this script (absolute, without changing PWD) +# INFRA is this repository; CODE is the workspace one level up that holds it +# next to the code checkouts. The codes resolve dependencies as $CODE/. set SCRIPT_DIR (dirname (status --current-filename)) if type -q path - set -gx CODE (path resolve $SCRIPT_DIR) + set -gx INFRA (path resolve $SCRIPT_DIR) else if type -q realpath - set -gx CODE (realpath $SCRIPT_DIR) + set -gx INFRA (realpath $SCRIPT_DIR) else # Fallback: temporarily cd and restore set -l __oldpwd $PWD cd $SCRIPT_DIR - set -gx CODE $PWD + set -gx INFRA $PWD cd $__oldpwd end +set -gx CODE (path resolve $INFRA/..) -echo "Setting CODE environment to: $CODE" +echo "Setting CODE workspace to: $CODE (infra: $INFRA)" # Check if the OS is macOS if test (uname) = "Darwin" @@ -76,31 +78,31 @@ function set_branch_fish else if test -n "$CI_COMMIT_REF_NAME" set -gx CODE_BRANCH $CI_COMMIT_REF_NAME else - # Avoid directory changes; query git directly in $CODE - set -gx CODE_BRANCH (git -C $CODE branch --show-current) + # Avoid directory changes; query git directly in $INFRA + set -gx CODE_BRANCH (git -C $INFRA branch --show-current) if test -z "$CODE_BRANCH" - set -gx CODE_BRANCH (git -C $CODE rev-parse --short HEAD) + set -gx CODE_BRANCH (git -C $INFRA rev-parse --short HEAD) end end - echo "Activating $CODE on branch $CODE_BRANCH" + echo "Activating $INFRA on branch $CODE_BRANCH" end # Set up paths set_branch_fish -add_to_path_fish $CODE/scripts -add_to_path_fish $CODE/local/bin -add_to_path_fish $CODE/bin +add_to_path_fish $INFRA/scripts +add_to_path_fish $INFRA/local/bin +add_to_path_fish $INFRA/bin add_to_library_path_fish $CODE/libneo/build -add_to_library_path_fish $CODE/local/lib -add_to_library_path_fish $CODE/lib +add_to_library_path_fish $INFRA/local/lib +add_to_library_path_fish $INFRA/lib # Activate Python virtual environment -if test -f $CODE/.venv/bin/activate.fish - source $CODE/.venv/bin/activate.fish +if test -f $INFRA/.venv/bin/activate.fish + source $INFRA/.venv/bin/activate.fish else echo "Warning: Python virtual environment fish activation script not found" - echo "Run: python -m venv $CODE/.venv to create it" + echo "Run: python -m venv $INFRA/.venv to create it" end # Load modules if available @@ -115,6 +117,6 @@ if command -v code > /dev/null alias vscode="code $CODE" end -module use -a $CODE/modules +module use -a $INFRA/modules echo "Fish shell activation complete!" diff --git a/activate.sh b/activate.sh index 4e17102..f6dfbb6 100644 --- a/activate.sh +++ b/activate.sh @@ -12,7 +12,11 @@ else SCRIPT_SOURCE="$0" fi -export CODE="$( cd "$( dirname "$SCRIPT_SOURCE" )" && pwd )" +# INFRA is this repository. CODE is the workspace one level up that holds it +# next to the actual code checkouts (libneo, SIMPLE, ...). The codes resolve +# their dependencies as $CODE/ (find_or_fetch), so CODE is the parent. +export INFRA="$( cd "$( dirname "$SCRIPT_SOURCE" )" && pwd )" +export CODE="$( cd "$INFRA/.." && pwd )" # Check if the OS is macOS if [ "$(uname)" = "Darwin" ]; then @@ -86,22 +90,22 @@ if [ -n "$FISH_VERSION" ]; then # Fish shell detected - redirect to dedicated fish script echo "Fish shell detected!" echo "Please use the dedicated fish script instead:" - echo " source $CODE/activate.fish" + echo " source $INFRA/activate.fish" echo "" echo "This script (activate.sh) is designed for bash/zsh compatibility." return 1 else # Bash/Zsh setup (original behavior) - source $CODE/scripts/util.sh + source $INFRA/scripts/util.sh set_branch - add_to_path $CODE/scripts - add_to_path $CODE/local/bin - add_to_path $CODE/bin + add_to_path $INFRA/scripts + add_to_path $INFRA/local/bin + add_to_path $INFRA/bin export PATH add_to_library_path $CODE/libneo/build - add_to_library_path $CODE/local/lib - add_to_library_path $CODE/lib + add_to_library_path $INFRA/local/lib + add_to_library_path $INFRA/lib if [ -n "$GSL_ROOT_DIR" ]; then add_to_library_path $GSL_ROOT_DIR/lib add_to_path $GSL_ROOT_DIR/bin @@ -126,7 +130,7 @@ else fi export LD_LIBRARY_PATH - source $CODE/.venv/bin/activate + source $INFRA/.venv/bin/activate if [ -f /etc/profile.d/modules.sh ]; then unalias ml 2>/dev/null @@ -134,6 +138,6 @@ else fi if command -v module >/dev/null 2>&1; then - module use -a $CODE/modules + module use -a $INFRA/modules fi fi diff --git a/docs/development-model.md b/docs/development-model.md new file mode 100644 index 0000000..69a6034 --- /dev/null +++ b/docs/development-model.md @@ -0,0 +1,133 @@ +# Development model (proposed) + +Status: proposed, 2026-05. Open for group discussion before adoption. + +Conventions for how the plasma codes and their shared dependencies are built and +released. This is a proposal from a design session, not settled policy. + +## Workspace layout + +`$CODE` is a plain workspace directory. It holds: + + $CODE/ + infra/ this repository: activation, setup scripts, modules, .venv + external/ prebuilt third-party libraries, shared by all codes + libneo/ code checkout + SIMPLE/ code checkout + ... + +Activation exports `INFRA=$CODE/infra` and `CODE` as its parent. Infra-private +paths (`scripts`, `.venv`, `modules`) live under `$INFRA`. Codes read prebuilt +third-party libraries from `$CODE/external`. First-party dependencies are fetched +at a resolved ref, not read from the sibling checkouts (see Dependency graph), so +a local checkout is for editing that code, not for wiring one code against +another. `infra` is no longer the workspace root, so its git tree stops seeing +the sibling checkouts. + +## Dependency graph + +Each code declares its first-party dependencies in CMake through `find_or_fetch`, +which fetches each one from GitHub at a resolved ref (see The one convention). +There is no local-path shortcut: a sibling checkout is not consulted, so the +build is reproducible from the declaration alone. The graph is self-describing: +read it by inverting those declarations rather than keeping a list by hand. + +Current hub: libneo. Consumers with a declared edge: SIMPLE, NEO-2, NEO-RT, +MEPHIT, KAMEL, rabe. Secondary first-party dependency: fortplot (SIMPLE, +NEO-RT). Single-consumer leaves: spline (NEO-RT), vode (NEO-RT), quadpack +(KAMEL). GORILLA and most small projects declare no first-party edge. + +## Integration testing + +The old umbrella CI built every code on each push to infra. It never passed (0 +of 94 runs) because it built the unpinned tips of six repos in one sequential +job against a frozen release tarball. We retire it. + +Replacement, in two layers: + +1. Per-code CI at the source. Each code builds against the libneo release branch + it tracks, so a breaking change surfaces in the pull request that caused it. +2. Release-time reverse-dependency validation, owned by the upstream. Before + libneo releases, it dispatches each tracked consumer's own CI against the + candidate and gates the release on the result. + +A tracked downstream is a code with a real `find_or_fetch` edge to the upstream +and its own CI/CD. Both are checkable, so the set is computed, not curated, and +the long tail of small projects drops out automatically. + +## The one convention + +Every tracked downstream resolves each first-party dependency through one ladder +in `find_or_fetch`: + +1. `_REF` (environment or CMake cache): a branch, tag, or commit. It is + validated against the remote and ignored if absent. The upstream sets it to + build the downstream against a candidate. +2. `_RELEASE` (committed cache variable): the release branch the code tracks + by default. Never main. +3. the current branch if it exists in the remote, otherwise main. + +`LIBNEO_REF` and `LIBNEO_RELEASE` are the instances for libneo. The override lets +the upstream build any downstream against any candidate ref with no commit to the +downstream. It is the multi-repo stand-in for a global build graph, and the only +piece standardized across the codes. + +## Release model + +Codes track the latest libneo release branch. Tags are reproducibility +snapshots, not what a code follows. + +1. libneo cuts `release/YY.MINOR` off main. +2. For each tracked downstream, the release workflow dispatches the downstream's + own CI with `LIBNEO_REF=release/YY.MINOR` (a `workflow_dispatch` input: no + commit, no pull request). The downstream builds and tests its main against the + candidate, golden records included. +3. libneo polls the dispatched runs and gates on all of them passing. +4. On all-green, a bot opens a bump pull request in each pinning downstream that + sets `LIBNEO_RELEASE` to the new branch, and enables auto-merge. Each + downstream's own CI gates that merge; no human step. +5. Tagging `YY.MINOR.PATCH` at the branch head is a separate, on-demand step. The + tag is a citation and reproducibility snapshot; downstreams keep tracking the + branch. + +Properties: + +- A downstream's committed pin is a release branch, never main. Exact reproduction + uses a tag. +- Validation needs green CI, not merged pull requests, so a slow downstream never + blocks the upstream. +- The gate dispatches each downstream's existing CI by name (`release/downstreams` + lists the workflow file per repo). There is no separate integration workflow to + maintain. +- Transitive consumers are listed explicitly. NEO-RT reaches libneo through NEO-2, + so its CI sets `LIBNEO_REF` as an environment variable and it propagates to the + libneo fetch inside the NEO-2 that NEO-RT builds. +- No automatic downstream releases. A downstream releases on its own cadence, and + only when behavior changed (for example a libneo change that alters NEO-2 + output, NEO-2 being itself an upstream of NEO-RT). + +Patch releases reuse the branch: cherry-pick onto `release/YY.MINOR`, re-run the +downstream dispatch, tag `YY.MINOR.PATCH`. + +## Versioning + +`YY.MINOR.PATCH`. `YY` is the two-digit year the release branch is cut, not the +year it finishes. MINOR counts releases within that year; PATCH counts fixes on +a release branch. Derive the version from the git tag (for example via +`setuptools_scm`) so the tag is the single source of truth, and feed CMake from +the same source. + +No leading zeros in the version. PEP 440 normalizes `26.05` to `26.5`, so a +packaged library must use `26.5` or its metadata disagrees with the tag. Every +component is then a plain integer, which keeps git, CMake `project(VERSION)`, +Spack, and PEP 440 in agreement. + +Teaching codes keep the semester scheme `YY.0M` (`26.03`, `26.10`). They are +end-user deliverables, not packaged libraries, so the leading-zero rule does not +reach them. + +Rationale for CalVer over SemVer: the release process verifies downstream +compatibility by building, so the number need not carry SemVer's compatibility +promise. Its remaining job is to identify the dated snapshot, which is what +citation and reproducibility want. Precedent in scientific software includes +GROMACS (`2026.2`) and FEniCS (`2019.1.0`). diff --git a/docs/templates/downstream-integration.yml b/docs/templates/downstream-integration.yml new file mode 100644 index 0000000..6073c40 --- /dev/null +++ b/docs/templates/downstream-integration.yml @@ -0,0 +1,29 @@ +# Snippet: make a downstream's existing CI dispatchable by an upstream release. +# +# There is no separate integration workflow. Add these three pieces to the +# downstream's existing CI workflow (the one that already builds and tests it). +# An upstream libneo release then dispatches that workflow by name with a +# candidate ref; the run builds the downstream's own main against it, with no +# commit and no pin change, and the upstream polls the conclusion to gate. +# +# Prerequisite: this code's find_or_fetch honors LIBNEO_REF (see the _REF +# convention in docs/development-model.md). + +# 1. Accept a ref from the dispatcher (add to `on:`). +on: + workflow_dispatch: + inputs: + libneo_ref: + description: libneo branch, tag or commit to build against + required: false + default: '' + +# 2. Map it to the resolver override. Empty on push/PR, so normal builds keep the +# committed LIBNEO_RELEASE. Set it at job/workflow level, except where the job +# also builds a reference version against a different libneo (then scope it to +# the single build step under test). +env: + LIBNEO_REF: ${{ inputs.libneo_ref }} + +# 3. Run the full job (golden records included) on dispatch. If a job `if:` guard +# only admits push/pull_request, add `|| github.event_name == 'workflow_dispatch'`. diff --git a/docs/templates/upstream-release.yml b/docs/templates/upstream-release.yml new file mode 100644 index 0000000..a4788ef --- /dev/null +++ b/docs/templates/upstream-release.yml @@ -0,0 +1,17 @@ +# Pointer, not a template. +# +# The upstream release gate is implemented, not templated. The canonical version +# lives in the hub repo: +# +# itpplasma/libneo: .github/workflows/release.yml +# release/downstreams (blocking set + per-repo CI file) +# release/check-downstreams.sh (advisory drift check) +# +# It dispatches each downstream's existing CI (by the workflow file named in +# release/downstreams) with LIBNEO_REF set to the release branch, polls each run, +# and gates on all-green. On a new release branch it opens auto-merge bump PRs +# that set each pinning downstream's LIBNEO_RELEASE to that branch; tagging +# YY.MINOR.PATCH is a separate reproducibility snapshot. +# +# Copy that workflow into another hub (for example fortplot) and swap libneo for +# the hub name. See docs/development-model.md for the model. diff --git a/external/.gitkeep b/external/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/external/intel/.gitkeep b/external/intel/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/images/base/cross_build_push.sh b/images/base/cross_build_push.sh index 5f5bcb8..fd9bdc9 100755 --- a/images/base/cross_build_push.sh +++ b/images/base/cross_build_push.sh @@ -1,3 +1,3 @@ #!/usr/bin/env bash docker pull debian:bookworm-slim -docker buildx build --platform linux/amd64,linux/arm64 -f $CODE/images/base/Dockerfile -t ghcr.io/itpplasma/base . --push +docker buildx build --platform linux/amd64,linux/arm64 -f $INFRA/images/base/Dockerfile -t ghcr.io/itpplasma/base . --push diff --git a/images/devcontainer/cross_build_push.sh b/images/devcontainer/cross_build_push.sh index fe00bdf..7db59fe 100755 --- a/images/devcontainer/cross_build_push.sh +++ b/images/devcontainer/cross_build_push.sh @@ -1,3 +1,3 @@ #!/usr/bin/env bash docker pull ghcr.io/itpplasma/devcontainer -docker buildx build --platform linux/amd64,linux/arm64 -f $CODE/images/devcontainer/Dockerfile -t ghcr.io/itpplasma/devcontainer . --push +docker buildx build --platform linux/amd64,linux/arm64 -f $INFRA/images/devcontainer/Dockerfile -t ghcr.io/itpplasma/devcontainer . --push diff --git a/images/devel-tex/cross_build_push.sh b/images/devel-tex/cross_build_push.sh index 9df3ce7..70bdb5f 100755 --- a/images/devel-tex/cross_build_push.sh +++ b/images/devel-tex/cross_build_push.sh @@ -1,3 +1,3 @@ #!/usr/bin/env bash docker pull ghcr.io/itpplasma/devel -docker buildx build --platform linux/amd64,linux/arm64 -f $CODE/images/devel-tex/Dockerfile -t ghcr.io/itpplasma/devel-tex . --push +docker buildx build --platform linux/amd64,linux/arm64 -f $INFRA/images/devel-tex/Dockerfile -t ghcr.io/itpplasma/devel-tex . --push diff --git a/images/devel/cross_build_push.sh b/images/devel/cross_build_push.sh index 6277f25..e1cbe38 100755 --- a/images/devel/cross_build_push.sh +++ b/images/devel/cross_build_push.sh @@ -1,3 +1,3 @@ #!/usr/bin/env bash docker pull ghcr.io/itpplasma/base -docker buildx build --platform linux/amd64,linux/arm64 -f $CODE/images/devel/Dockerfile -t ghcr.io/itpplasma/devel . --push +docker buildx build --platform linux/amd64,linux/arm64 -f $INFRA/images/devel/Dockerfile -t ghcr.io/itpplasma/devel . --push diff --git a/libneo b/libneo deleted file mode 160000 index d3ecd23..0000000 --- a/libneo +++ /dev/null @@ -1 +0,0 @@ -Subproject commit d3ecd23926973faeb5294d16273b36402373e4bd diff --git a/scripts/docker_build_push.sh b/scripts/docker_build_push.sh index f3f63b3..759eada 100755 --- a/scripts/docker_build_push.sh +++ b/scripts/docker_build_push.sh @@ -1,2 +1,2 @@ #!/usr/bin/env bash -docker buildx build --platform linux/amd64,linux/arm64 -t ghcr.io/itpplasma/$1 -f $CODE/images/$1/Dockerfile . --push +docker buildx build --platform linux/amd64,linux/arm64 -t ghcr.io/itpplasma/$1 -f $INFRA/images/$1/Dockerfile . --push diff --git a/scripts/docker_build_push_all.sh b/scripts/docker_build_push_all.sh index 78a5946..ebbaa9d 100755 --- a/scripts/docker_build_push_all.sh +++ b/scripts/docker_build_push_all.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash -$CODE/images/base/cross_build_push.sh -$CODE/images/devel/cross_build_push.sh -$CODE/images/devel-tex/cross_build_push.sh -$CODE/images/devcontainer/cross_build_push.sh +$INFRA/images/base/cross_build_push.sh +$INFRA/images/devel/cross_build_push.sh +$INFRA/images/devel-tex/cross_build_push.sh +$INFRA/images/devcontainer/cross_build_push.sh docker pull ghcr.io/itpplasma/devcontainer diff --git a/scripts/machines/setup_viper.sh b/scripts/machines/setup_viper.sh index cbb0322..d80a27d 100644 --- a/scripts/machines/setup_viper.sh +++ b/scripts/machines/setup_viper.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -source $CODE/machines/init_viper.sh +source $INFRA/machines/init_viper.sh mkdir -p $HOME/.local/lib ln -s $MKL_PARTS_HOME/lib/libmkl_blas.so $HOME/.local/lib/libblas.so diff --git a/scripts/setup.sh b/scripts/setup.sh index 4712452..06f19fb 100755 --- a/scripts/setup.sh +++ b/scripts/setup.sh @@ -4,21 +4,27 @@ set -e SCRIPTPATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -export CODE=$SCRIPTPATH/.. +export INFRA="$( cd "$SCRIPTPATH/.." && pwd )" +export CODE="$( cd "$INFRA/.." && pwd )" export GIT_SSH_COMMAND="ssh -o StrictHostKeyChecking=accept-new" -$CODE/scripts/setup/venv.sh -source $CODE/.venv/bin/activate +# venv and requirements.txt live at the infra root +pushd $INFRA + $INFRA/scripts/setup/venv.sh + source $INFRA/.venv/bin/activate +popd +# external prebuilt deps are workspace-shared; the codes read $CODE/external +mkdir -p $CODE/external pushd $CODE/external - $CODE/scripts/setup/openblas.sh - $CODE/scripts/setup/gsl.sh - $CODE/scripts/setup/fgsl.sh - $CODE/scripts/setup/fftw.sh - $CODE/scripts/setup/netcdf.sh - $CODE/scripts/setup/triangle.sh + $INFRA/scripts/setup/openblas.sh + $INFRA/scripts/setup/gsl.sh + $INFRA/scripts/setup/fgsl.sh + $INFRA/scripts/setup/fftw.sh + $INFRA/scripts/setup/netcdf.sh + $INFRA/scripts/setup/triangle.sh popd pushd $CODE - $CODE/scripts/setup/libneo.sh + $INFRA/scripts/setup/libneo.sh popd diff --git a/scripts/setup/ascot5.sh b/scripts/setup/ascot5.sh index 834b63d..df2b7fc 100755 --- a/scripts/setup/ascot5.sh +++ b/scripts/setup/ascot5.sh @@ -2,7 +2,7 @@ set -e -source $CODE/scripts/util.sh +source $INFRA/scripts/util.sh echo "Setting up ASCOT5..." diff --git a/scripts/setup/compiler_intel.sh b/scripts/setup/compiler_intel.sh index 2ec892d..a13e4c3 100755 --- a/scripts/setup/compiler_intel.sh +++ b/scripts/setup/compiler_intel.sh @@ -45,5 +45,5 @@ export CC=icx export CXX=icpx pushd $CODE/external/intel - source $CODE/scripts/setup/netcdf.sh + source $INFRA/scripts/setup/netcdf.sh popd diff --git a/scripts/setup/devcontainer.sh b/scripts/setup/devcontainer.sh index 93747bb..3a28d51 100755 --- a/scripts/setup/devcontainer.sh +++ b/scripts/setup/devcontainer.sh @@ -2,17 +2,21 @@ export GIT_HTTPS=1 export CODE_TEMPLATE=/usr/local/src/code_template -export CODE=/workspaces/code mkdir -p /workspaces mkdir -p /usr/local/src +# infra repo at /workspaces/code, code checkouts as siblings under /workspaces cd /workspaces git clone https://github.com/itpplasma/code.git code -cd $CODE +cd /workspaces/code source scripts/setup.sh -mv $CODE $CODE_TEMPLATE +# setup.sh puts libneo and external in the workspace ($CODE = /workspaces); +# stash them inside the infra template so postCreateCommand.sh can restore them. +mv /workspaces/libneo /workspaces/code/libneo +mv /workspaces/external /workspaces/code/external +mv /workspaces/code $CODE_TEMPLATE rm -rf /workspaces diff --git a/scripts/setup/lfortran.sh b/scripts/setup/lfortran.sh index 8942662..4155c9e 100755 --- a/scripts/setup/lfortran.sh +++ b/scripts/setup/lfortran.sh @@ -6,7 +6,7 @@ sudo apt update && sudo apt install -y --no-install-recommends llvm-dev curl -L https://github.com/nlohmann/json/archive/refs/tags/v3.11.3.tar.gz -o - | tar xz mkdir -p json-3.11.3/build pushd json-3.11.3/build -cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$CODE/.venv +cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$INFRA/.venv make -j$(nproc) make install popd @@ -14,7 +14,7 @@ popd curl -L https://github.com/jupyter-xeus/xeus/archive/refs/tags/5.1.0.tar.gz -o - | tar xz mkdir -p xeus-5.1.0/build pushd xeus-5.1.0/build -cmake .. -D CMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$CODE/.venv +cmake .. -D CMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$INFRA/.venv make -j$(nproc) make install popd @@ -22,7 +22,7 @@ popd curl -L https://github.com/jupyter-xeus/xeus-zmq/archive/refs/tags/3.0.0.tar.gz -o - | tar xz mkdir -p xeus-zmq-3.0.0/build pushd xeus-zmq-3.0.0/build -cmake .. -D CMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$CODE/.venv +cmake .. -D CMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$INFRA/.venv make -j$(nproc) make install popd @@ -30,7 +30,7 @@ popd curl -L https://github.com/lfortran/lfortran/releases/download/v0.37.0/lfortran-0.37.0.tar.gz -o - | tar xz mkdir -p lfortran-0.37.0/build pushd lfortran-0.37.0/build -cmake .. -DCMAKE_BUILD_TYPE=Debug -DWITH_LLVM=yes -DCMAKE_INSTALL_PREFIX=$CODE/.venv -DWITH_XEUS=yes +cmake .. -DCMAKE_BUILD_TYPE=Debug -DWITH_LLVM=yes -DCMAKE_INSTALL_PREFIX=$INFRA/.venv -DWITH_XEUS=yes make -j$(nproc) make install popd diff --git a/scripts/setup/libneo.sh b/scripts/setup/libneo.sh index 5227499..7ee1551 100755 --- a/scripts/setup/libneo.sh +++ b/scripts/setup/libneo.sh @@ -2,7 +2,7 @@ set -e -source $CODE/scripts/util.sh +source $INFRA/scripts/util.sh set_branch echo "Building and installing 'libneo'..." @@ -11,6 +11,6 @@ if [ ! -d "libneo" ] ; then clone_github libneo fi pushd libneo -$CODE/scripts/checkout_branch.sh $CODE_BRANCH +$INFRA/scripts/checkout_branch.sh $CODE_BRANCH pip install --verbose --no-build-isolation -e . popd diff --git a/scripts/setup/mephit.sh b/scripts/setup/mephit.sh index 964a0ed..896024b 100755 --- a/scripts/setup/mephit.sh +++ b/scripts/setup/mephit.sh @@ -2,11 +2,11 @@ set -e source /etc/profile.d/modules.sh -module use -a $CODE/modules +module use -a $INFRA/modules module load mephit pushd MEPHIT - $CODE/scripts/checkout_branch.sh $CODE_BRANCH + $INFRA/scripts/checkout_branch.sh $CODE_BRANCH make pip install -e . popd diff --git a/scripts/setup/omfit.sh b/scripts/setup/omfit.sh index 68ee35f..cf1beff 100755 --- a/scripts/setup/omfit.sh +++ b/scripts/setup/omfit.sh @@ -11,4 +11,4 @@ cd OMFIT-source git submodule update --init omas install/install.sh mkdir -p $HOME/.LICENSES -cp $CODE/scripts/setup/omfit/LICENSES/* $HOME/.LICENSES/ +cp $INFRA/scripts/setup/omfit/LICENSES/* $HOME/.LICENSES/ diff --git a/scripts/setup/stellopt.sh b/scripts/setup/stellopt.sh index a8e09ae..bbc070b 100755 --- a/scripts/setup/stellopt.sh +++ b/scripts/setup/stellopt.sh @@ -1,7 +1,8 @@ #!/usr/bin/env bash set -e -# Ensure CODE_ROOT is exported for make configs (can't use CODE - build_all uses it) +# CODE_ROOT feeds the STELLOPT make configs, which read $(CODE_ROOT)/external/... +# That tree lives in the infra repo, so point it at $INFRA. export CODE_ROOT="$CODE" # Create ~/bin for libstell symlinks and ensure it's in PATH @@ -17,24 +18,24 @@ fi select_machine() { case "$(uname -s)" in Darwin) - cp $CODE/scripts/setup/stellopt/make_osx_brew_m1.inc $CODE/external/STELLOPT/SHARE + cp $INFRA/scripts/setup/stellopt/make_osx_brew_m1.inc $CODE/external/STELLOPT/SHARE export MACHINE=osx_brew_m1 ;; Linux) # Check for VSC5 cluster (hostname contains vsc or l5 node pattern) if [[ "$(hostname)" == *vsc* ]] || [[ "$(hostname)" == l5* ]] || [[ -n "$VSC_INSTITUTE" ]]; then - cp $CODE/scripts/setup/stellopt/make_vsc5.inc $CODE/external/STELLOPT/SHARE + cp $INFRA/scripts/setup/stellopt/make_vsc5.inc $CODE/external/STELLOPT/SHARE export MACHINE=vsc5 # Check for scluster elif [[ "$(hostname)" == scluster* ]]; then - cp $CODE/scripts/setup/stellopt/make_scluster.inc $CODE/external/STELLOPT/SHARE + cp $INFRA/scripts/setup/stellopt/make_scluster.inc $CODE/external/STELLOPT/SHARE export MACHINE=scluster # Detect distro family from /etc/os-release elif [ -f /etc/os-release ]; then . /etc/os-release case "$ID" in arch|manjaro|cachyos|endeavouros|garuda|artix) - cp $CODE/scripts/setup/stellopt/make_arch_linux.inc $CODE/external/STELLOPT/SHARE + cp $INFRA/scripts/setup/stellopt/make_arch_linux.inc $CODE/external/STELLOPT/SHARE export MACHINE=arch_linux ;; rhel|centos|fedora|almalinux|rocky) @@ -46,7 +47,7 @@ select_machine() { *) case "$ID_LIKE" in *arch*) - cp $CODE/scripts/setup/stellopt/make_arch_linux.inc $CODE/external/STELLOPT/SHARE + cp $INFRA/scripts/setup/stellopt/make_arch_linux.inc $CODE/external/STELLOPT/SHARE export MACHINE=arch_linux ;; *rhel*|*centos*|*fedora*) @@ -58,7 +59,7 @@ select_machine() { *) # Fallback: check for pacman (Arch-based) if command -v pacman &>/dev/null; then - cp $CODE/scripts/setup/stellopt/make_arch_linux.inc $CODE/external/STELLOPT/SHARE + cp $INFRA/scripts/setup/stellopt/make_arch_linux.inc $CODE/external/STELLOPT/SHARE export MACHINE=arch_linux else export MACHINE=ubuntu @@ -79,7 +80,7 @@ select_machine() { } apply_patches() { - local patches_dir="$CODE/scripts/setup/stellopt/patches" + local patches_dir="$INFRA/scripts/setup/stellopt/patches" if [ -d "$patches_dir" ]; then for patch in "$patches_dir"/*.patch; do [ -f "$patch" ] || continue diff --git a/scripts/setup/vmec2000.sh b/scripts/setup/vmec2000.sh index 58b7d95..b80ffe2 100755 --- a/scripts/setup/vmec2000.sh +++ b/scripts/setup/vmec2000.sh @@ -8,8 +8,8 @@ if [ ! -d "VMEC2000" ] ; then fi pushd VMEC2000 -cp $CODE/scripts/setup/cmake_config_file_vmec2000.json cmake_config_file.json -sed -i "s|{CODE}|$CODE|g" cmake_config_file.json +cp $INFRA/scripts/setup/cmake_config_file_vmec2000.json cmake_config_file.json +sed -i "s|{CODE}|$INFRA|g" cmake_config_file.json cmake -S. -Bbuild -GNinja -DNETCDF_INC_PATH=/usr/include -DSCALAPACK_LIB_NAME=libscalapack-openmpi.so -DBLA_VENDOR=OpenBLAS pushd build ninja diff --git a/scripts/util.sh b/scripts/util.sh index d4886e0..a43740a 100644 --- a/scripts/util.sh +++ b/scripts/util.sh @@ -17,12 +17,12 @@ set_branch() { elif [ -n "$CI_COMMIT_REF_NAME" ]; then export CODE_BRANCH=$CI_COMMIT_REF_NAME else - pushd $CODE + pushd $INFRA export CODE_BRANCH=$(git branch --show-current) popd fi - echo "Activating $CODE on branch $CODE_BRANCH" + echo "Activating $INFRA on branch $CODE_BRANCH" } add_to_path() { diff --git a/tests/NEO-RT/benchmark_with_NEO_2/benchmark_with_NEO_2.ipynb b/tests/NEO-RT/benchmark_with_NEO_2/benchmark_with_NEO_2.ipynb index 64f93f2..a2558cc 100644 --- a/tests/NEO-RT/benchmark_with_NEO_2/benchmark_with_NEO_2.ipynb +++ b/tests/NEO-RT/benchmark_with_NEO_2/benchmark_with_NEO_2.ipynb @@ -20,7 +20,7 @@ "surfs = np.arange(0.78, 1.00, 0.02)\n", "runs = [f\"{surf:.2f}\".replace(\".\", \"p\") for surf in surfs]\n", "\n", - "run_dir = os.path.join(os.path.expandvars(\"$CODE/tests/NEO-RT/benchmark_with_NEO_2/RUN\"))\n", + "run_dir = os.path.join(os.path.expandvars(\"$INFRA/tests/NEO-RT/benchmark_with_NEO_2/RUN\"))\n", "if os.path.isdir(run_dir):\n", " os.system(f'rm -r {run_dir}')\n", "os.makedirs(run_dir)"