Skip to content

Commit

Permalink
Merge pull request #496 from taha-abdullah/dev
Browse files Browse the repository at this point in the history
Fastsurfer Singularity workflow to quick test new code before merging
  • Loading branch information
m-reuter authored Mar 28, 2024
2 parents 4424117 + 31842db commit 58820ee
Show file tree
Hide file tree
Showing 9 changed files with 603 additions and 1 deletion.
58 changes: 58 additions & 0 deletions .github/workflows/QUICKTEST.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# FastSurfer Singularity GitHub Actions Workflow

This GitHub Actions workflow is designed to automate the integration testing of new code into the FastSurfer repository using Singularity containers. The workflow is triggered whenever new code is pushed to the repository.

The workflow runs on a self-hosted runner labelled 'ci-gpu' to ensure security.

## Jobs

The workflow consists of several jobs that are executed in sequence:

### Checkout

This job checks out the repository using the `actions/checkout@v2` action.

### Prepare Job

This job sets up the necessary environments for the workflow. It depends on the successful completion of the `checkout` job. The environments set up in this job include:

- Python 3.10, using the `actions/setup-python@v3` action.
- Go, using the `actions/setup-go@v5` action with version `1.13.1`.
- Singularity, using the `eWaterCycle/setup-singularity@v7` action with version `3.8.3`.

### Build Singularity Image

This job builds a Docker image and converts it to a Singularity image. It depends on the successful completion of the `prepare-job`. The Docker image is built using a Python script `Docker/build.py` with the `--device cuda --tag fastsurfer_gpu:cuda` flags. The Docker image is then converted to a Singularity image.

### Run FastSurfer

This job runs FastSurfer on sample MRI data using the Singularity image built in the previous job. It depends on the successful completion of the `build-singularity-image` job. The Singularity container is executed with the `--nv`, `--no-home`, and `--bind` flags to enable GPU access, prevent home directory mounting, and bind the necessary directories respectively. The `FASTSURFER_HOME` environment variable is set to `/fastsurfer-dev` inside the container.

### Test File Existence

This job tests for the existence of certain files after running FastSurfer. It depends on the successful completion of the `run-fastsurfer` job. The test is performed using a Python script `test/test_file_existence.py`.

### Test Error Messages

This job tests for errors in log files after running FastSurfer. It runs on a self-hosted runner labeled `ci-gpu` and depends on the successful completion of both the `run-fastsurfer` and `test-file-existence` jobs. The test is performed using a Python script `test/test_error_messages.py`.

## Usage

To use this workflow, you need to have a self-hosted runner labeled `ci-gpu` set up on your machine. You also need to update the environment variables of the runner, by going to `/home/your_runner/.env` file and adding the following environment variables with the actual paths you want to use.


### Environment variables
`RUNNER_FS_MRI_DATA`: Path to MRI Data

`RUNNER_FS_OUTPUT`: Path to Output directory

`RUNNER_FS_LICENSE`: Path to License directory

`RUNNER_SINGULARITY_IMGS`: Path to where Singularity images should be stored

`RUNNER_FS_OUTPUT_FILES`: Path to output files to be tested

`RUNNER_FS_OUTPUT_LOGS`: Path to output log files to check for errors


Once everything is set up, you can trigger the workflow manually from the GitHub Actions tab in your repository, as well as by pushing code to the repository.
90 changes: 90 additions & 0 deletions .github/workflows/quicktest.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
name: FastSurfer Singularity

on:
workflow_dispatch:

jobs:
# Checkout repo
checkout:
runs-on: ci-gpu
steps:
- uses: actions/checkout@v2

# Prepare job: Set up Python, Go, Singularity
prepare-job:
runs-on: ci-gpu
needs: checkout
steps:
- name: Set up Python 3.10
uses: actions/setup-python@v3
with:
python-version: "3.10"
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '^1.13.1' # The Go version to download (if necessary) and use.
- name: Set up Singularity
uses: eWaterCycle/setup-singularity@v7
with:
singularity-version: 3.8.3

# Build Docker Image and convert it to Singularity
build-singularity-image:
runs-on: ci-gpu
needs: prepare-job
steps:
- name: Build Docker Image and convert to Singularity
run: |
cd $RUNNER_SINGULARITY_IMGS
FILE="fastsurfer-gpu.sif"
if [ ! -f "$FILE" ]; then
# If the file does not exist, build the file
echo "SIF File does not exist. Building file."
PYTHONPATH=$PYTHONPATH
cd $PYTHONPATH
python3 Docker/build.py --device cuda --tag fastsurfer_gpu:cuda
cd $RUNNER_SINGULARITY_IMGS
singularity build --force fastsurfer-gpu.sif docker-daemon://fastsurfer_gpu:cuda
else
echo "File already exists"
cd $PYTHONPATH
fi
# Run FastSurfer on MRI data
run-fastsurfer:
runs-on: ci-gpu
needs: build-singularity-image
steps:
- name: Run FastSurfer
run: |
singularity exec --nv \
--no-home \
--bind $GITHUB_WORKSPACE:/fastsurfer-dev \
--env FASTSURFER_HOME=/fastsurfer-dev \
-B $RUNNER_FS_MRI_DATA:/data \
-B $RUNNER_FS_OUTPUT:/output \
-B $RUNNER_FS_LICENSE:/fs_license \
$RUNNER_SINGULARITY_IMGS/fastsurfer-gpu.sif \
/fastsurfer/run_fastsurfer.sh \
--fs_license /fs_license/.license \
--t1 /data/subjectx/orig.mgz \
--sid subjectX --sd /output \
--parallel --3T
# Test file existence
test-file-existence:
runs-on: ci-gpu
needs: run-fastsurfer
steps:
- name: Test File Existence
run: |
python3 test/quick_test/test_file_existence.py $RUNNER_FS_OUTPUT_FILES
# Test for errors in log files
test-error-messages:
runs-on: ci-gpu
needs: [run-fastsurfer, test-file-existence]
steps:
- name: Test Log Files For Error Messages
run: |
python3 test/quick_test/test_errors.py $RUNNER_FS_OUTPUT_LOGS
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/BUILD.info
/.idea/**
/.idea/**
/rough_work/**
8 changes: 8 additions & 0 deletions test/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@



__all__ = [ # This is a list of modules that should be imported when using the import * syntax
'test_file_existence',
'test_error_messages',
'test_errors'
]
Empty file added test/quick_test/__init__.py
Empty file.
11 changes: 11 additions & 0 deletions test/quick_test/data/errors.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
errors:
- "error"
- "error:"
- "exception"
- "traceback"

whitelist:
- "without error"
- "not included"
- "distance"
- "correcting"
Loading

0 comments on commit 58820ee

Please sign in to comment.