Singularity

Visão Geral

O que é singularidade

Executar o Docker no SLURM é um problema de segurança (por exemplo, executando como root, tendo a capacidade de montar qualquer diretório). A alternativa é usar o Singularity, que é uma solução popular no mundo de HPC.

Existe um bom nível de compatibilidade entre Docker e Singularity, e podemos encontrar muitas alegações exageradas sobre a capacidade de converter contêineres do Docker para Singularity sem qualquer atrito. Muitas vezes, imagens do DockerHub são 100% compatíveis com o Singularity e podem ser usadas sem atrito, mas as coisas ficam complicadas quando tentamos converter nossos próprios arquivos de construção do Docker em receitas do Singularity.

Visão gerald dos passos usados na prática

Na maioria das vezes, o processo para criar e usar um contêiner Singularity é:

  • No seu computador Linux (em casa ou no trabalho)

    • selecione uma imagem Docker do DockerHub (por exemplo, pytorch/pytorch)

    • crie um arquivo de receita para o Singularity que comece com essa imagem do DockerHub

    • construa o arquivo de receita, criando assim o arquivo de imagem (por exemplo, my-pytorch-image.sif)

    • teste seu contêiner Singularity antes de enviá-lo para o cluster

    • rsync -av my-pytorch-image.sif <login-node>:Documents/my-singularity-images

  • No nó de login desse cluster

    • enfileire seus trabalhos com sbatch ...

    • (observe que seus trabalhos copiarão o arquivo my-pytorch-image.sif para $SLURM_TMPDIR e então iniciarão o Singularity com essa imagem) faça outra coisa enquanto espera que eles terminem

    • enfileire mais trabalhos com o mesmo my-pytorch-image.sif, reutilizando-o várias vezes

Nas próximas seções, você encontrará exemplos específicos ou dicas para realizar na prática as etapas destacadas acima.

Não, não no MacOS

Singularity não funciona no MacOS, até a data desta escrita em 2021. Docker realmente não roda no MacOS, mas o Docker instala silenciosamente uma máquina virtual executando Linux, o que torna a experiência agradável, e o usuário não precisa se preocupar com os detalhes de como o Docker faz isso.

Dado sua origem em HPC, o Singularity não fornece esse tipo de experiência sem problemas no MacOS, embora tecnicamente seja possível executá-lo dentro de uma máquina virtual Linux no MacOS.

Onde construir imagens

Construir imagens do Singularity é uma tarefa bastante pesada, que pode levar 20 minutos se você tiver muitas etapas na sua receita. Isso torna uma tarefa ruim para rodar em os nós de login de nossos clusters, especialmente se precisar ser executado regularmente.

No cluster Mila, temos a sorte de ter acesso irrestrito à internet nos nós de computação, o que significa que qualquer pessoa pode solicitar um nó de CPU interativo (sem necessidade de GPU) e construir suas imagens lá sem problemas.

Aviso

Não construa imagens do Singularity do zero toda vez que executar um trabalho em um grande lote. Isso será um desperdício colossal de tempo de GPU e também de largura de banda da internet. Se você configurar seu fluxo de trabalho corretamente (por exemplo, usando caminhos de ligação para o seu código e dados), você pode passar meses reutilizando a mesma imagem do Singularity my-pytorch-image.sif.

Construindo os containers

Construir um container é como criar um novo ambiente, exceto que os containers são muito mais poderosos, pois são sistemas autocontidos. Com o Singularity, existem duas maneiras de construir containers.

A primeira é fazê-lo você mesmo, é como quando você compra um novo laptop Linux e não sabe muito bem o que precisa, se perceber que algo está faltando, você o instala. Aqui, você pode obter um container vanilla com o Ubuntu chamado sandbox, você faz o login e instala cada pacote por si mesmo. Esse procedimento pode levar tempo, mas permitirá que você entenda como as coisas funcionam e o que precisa ser feito. Isso é recomendado se você precisa descobrir como as coisas serão compiladas ou se deseja instalar pacotes na hora Nos referiremos a este procedimento como singularity sandboxes.

A segunda maneira é mais como se você soubesse o que quer, então você escreve uma lista de tudo o que precisa, envia para o Singularity e ele instalará tudo para você. Essas listas são chamadas de singularity recipes.

Primeira maneira: construir e usar um sandbox

Você pode se perguntar: Em qual máquina devo construir um container?

Antes de tudo, você precisa escolher onde construirá o seu container. Essa operação requer muita memória e alto uso da CPU.

Aviso

NÃO construa containers em nenhum nó de login!

  • (Recomendado para iniciantes) Se você precisar usar o apt-get, você deve construir

    o container em seu laptop com privilégios de superusuário. Você só precisará instalar o Singularity em seu laptop. Usuários de Windows/Mac podem ver there e usuários de Ubuntu/Debian podem usar diretamente:

    sudo apt-get install singularity-container
    

Nesse caso, para evitar muita entrada/saída (I/O) na rede, você deve definir o cache do Singularity localmente:

export SINGULARITY_CACHEDIR=$SLURM_TMPDIR
  • Se você não pode instalar o Singularity em seu laptop e deseja usar o apt-get,

    você pode usar o singularity-hub para construir seus containers e ler a seção Recipe_section.

Baixando containers da web.

Felizmente, você pode não precisar criar containers do zero, pois muitos já foram construídos para os softwares de deep learning mais comuns. Você pode encontrá-los na maioria em dockerhub.

Acesse dockerhub e selecione o container que você deseja baixar

Por exemplo, se você deseja obter a última versão do PyTorch com suporte para GPU (Substitua runtime por devel se precisar do conjunto completo de ferramentas do Cuda):

singularity pull docker://pytorch/pytorch:1.0.1-cuda10.0-cudnn7-runtime

Ou a última versão do TensorFlow:

singularity pull docker://tensorflow/tensorflow:latest-gpu-py3

Atualmente, a imagem baixada pytorch.simg ou tensorflow.simg é somente leitura, o que significa que você não poderá instalar nada nela. A partir de agora, o PyTorch será usado como exemplo. Se você estiver usando o TensorFlow, simplesmente substitua todas as ocorrências de pytorch por tensorflow.

Como adicionar ou instalar coisas em um container

O primeiro passo é transformar o seu container somente leitura pytorch-1.0.1-cuda10.0-cudnn7-runtime.simg em uma versão gravável que permitirá que você adicione pacotes.

Aviso

Dependendo da versão do singularity que você está usando, o singularity criará um container com a extensão .simg ou .sif. Se você estiver usando arquivos .sif, substitua todas as ocorrências de .simg por .sif.

Dica

Se você quiser usar o apt-get, deve colocar sudo antes dos comandos a seguir

Este comando criará uma imagem gravável na pasta pytorch.

singularity build --sandbox pytorch pytorch-1.0.1-cuda10.0-cudnn7-runtime.simg

Então você precisará do seguinte comando para fazer login dentro do container.

singularity shell --writable -H $HOME:/home pytorch

Assim que você entrar no container, pode usar o pip e instalar tudo o que precisar (ou usar apt-get se você construiu o container com sudo).

Aviso

O Singularity monta sua pasta pessoal, então se você instalar coisas no diretório $HOME do seu container, elas serão instaladas no seu $HOME real!

Você deve instalar seus pacotes em /usr/local.

Criando diretórios úteis

Um dos benefícios dos containers é que você poderá usá-los em diferentes clusters. No entanto, para cada cluster, a localização das pastas de datasets e experimentos pode ser diferente. Para ser invariante em relação a essas localizações, criaremos alguns pontos de montagem úteis dentro do container:

mkdir /dataset
mkdir /tmp_log
mkdir /final_log

A partir de agora, você não precisará mais se preocupar em especificar onde buscar seu conjunto de dados ao escrever seu código. Seu conjunto de dados estará sempre em /dataset, independentemente do cluster que você estiver usando.

Testes

Se você tem algum código que deseja testar antes de finalizar o seu contêiner, você tem duas opções. Você pode entrar no seu contêiner e executar o código Python dentro dele com:

singularity shell --nv pytorch

Ou você pode executar seu comando diretamente com:

singularity exec --nv pytorch Python YOUR_CODE.py

Dica

—nv permite que o container use GPUs. Você não precisa disso se não planeja usar uma GPU.

Aviso

Não se esqueça de limpar o cache dos pacotes que você instalou nos containers.

Criando uma nova imagem a partir do sandbox

Depois que tudo o que você precisa estiver instalado dentro do contêiner, você precisa convertê-lo de volta em uma imagem singularity somente leitura com:

singularity build pytorch_final.simg pytorch

Segunda opção: Use receitas

Uma receita do Singularity é um arquivo que inclui especificações sobre a instalação de software, variáveis de ambiente, arquivos a serem adicionados e metadados do contêiner. É um ponto de partida para projetar qualquer contêiner personalizado. Em vez de baixar um contêiner e instalar seus pacotes manualmente, você pode especificar neste arquivo os pacotes que deseja e, em seguida, construir seu contêiner a partir deste arquivo.

Aqui está um exemplo simples de uma receita do Singularity que instala alguns pacotes:

################# Header: Define the base system you want to use ################
# Reference of the kind of base you want to use (e.g., docker, debootstrap, shub).
Bootstrap: docker
# Select the docker image you want to use (Here we choose tensorflow)
From: tensorflow/tensorflow:latest-gpu-py3

################# Section: Defining the system #################################
# Commands in the %post section are executed within the container.
%post
        echo "Installing Tools with apt-get"
        apt-get update
        apt-get install -y cmake libcupti-dev libyaml-dev wget unzip
        apt-get clean
        echo "Installing things with pip"
        pip install tqdm
        echo "Creating mount points"
        mkdir /dataset
        mkdir /tmp_log
        mkdir /final_log


# Environment variables that should be sourced at runtime.
%environment
        # use bash as default shell
        SHELL=/bin/bash
        export SHELL

Um arquivo de receita contém duas partes: o “cabeçalho” (header) e “seções” (sections). No “cabeçalho”, você especifica qual sistema base deseja usar, pode ser qualquer contêiner do Docker ou do Singularity. Em “seções”, você pode listar as coisas que deseja instalar na subseção “post” ou listar as variáveis de ambiente que precisa carregar em cada execução na subseção “environment”. Para uma descrição mais detalhada, consulte singularity documentation.

Para construir um container singularity a partir de um arquivo de receita, você deve usar:

sudo singularity build <NAME_CONTAINER> <YOUR_RECIPE_FILES>

Aviso

Você sempre precisa usar o sudo ao construir um contêiner a partir de uma receita. Como não há acesso ao sudo no cluster, é necessário um computador pessoal ou o uso do singularity hub para construir um contêiner.

Construir receita no Singularity Hub

O Singularity Hub permite que os usuários criem contêineres a partir de receitas diretamente na nuvem do Singularity Hub, o que significa que você não precisa criar contêineres sozinho. Você precisa se registrar no singularity-hub e vincular sua conta do Singularity Hub à sua conta do GitHub, e então:

  1. Crie um novo repositório no Github.

  2. Adicione uma coleção no singularity-hub e selecione o repositório do Github que você criou.

  3. Clone o repositório do Github em seu computador.

$ git clone <url>
  1. Write the singularity recipe and save it as a file named Singularity.

  2. Git add Singularity, commit and push on the master branch

$ git add Singularity
$ git commit
$ git push origin master

Neste ponto, os robôs do singularity-hub irão construir o contêiner para você, e você poderá baixá-lo do site ou diretamente usando:

singularity pull shub://<github_username>/<repository_name>

Exemplo: Receita com OpenAI gym, MuJoCo e Miniworld

Aqui está um exemplo de como você pode usar uma receita do Singularity para instalar um ambiente complexo como o OpenAI gym, MuJoCo e Miniworld em um contêiner baseado em PyTorch.

#This is a dockerfile that sets up a full Gym install with test dependencies
Bootstrap: docker

# Here we ll build our container upon the pytorch container
From: pytorch/pytorch:1.0-cuda10.0-cudnn7-runtime

# Now we'll copy the mjkey file located in the current directory inside the container's root
# directory
%files
        mjkey.txt

# Then we put everything we need to install
%post
        export PATH=$PATH:/opt/conda/bin
        apt -y update && \
        apt install -y keyboard-configuration && \
        apt install -y \
        python3-dev \
        python-pyglet \
        python3-opengl \
        libhdf5-dev \
        libjpeg-dev \
        libboost-all-dev \
        libsdl2-dev \
        libosmesa6-dev \
        patchelf \
        ffmpeg \
        xvfb \
        libhdf5-dev \
        openjdk-8-jdk \
        wget \
        git \
        unzip && \
        apt clean && \
        rm -rf /var/lib/apt/lists/*
        pip install h5py

        # Download Gym and MuJoCo
        mkdir /Gym && cd /Gym
        git clone https://github.com/openai/gym.git || true && \
        mkdir /Gym/.mujoco && cd /Gym/.mujoco
        wget https://www.roboti.us/download/mjpro150_linux.zip  && \
        unzip mjpro150_linux.zip && \
        wget https://www.roboti.us/download/mujoco200_linux.zip && \
        unzip mujoco200_linux.zip && \
        mv mujoco200_linux mujoco200

        # Export global environment variables
        export MUJOCO_PY_MJKEY_PATH=/Gym/.mujoco/mjkey.txt
        export MUJOCO_PY_MUJOCO_PATH=/Gym/.mujoco/mujoco150/
        export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/Gym/.mujoco/mjpro150/bin
        export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/Gym/.mujoco/mujoco200/bin
        export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/bin
        cp /mjkey.txt /Gym/.mujoco/mjkey.txt
        # Install Python dependencies
        wget https://raw.githubusercontent.com/openai/mujoco-py/master/requirements.txt
        pip install -r requirements.txt
        # Install Gym and MuJoCo
        cd /Gym/gym
        pip install -e '.[all]'
        # Change permission to use mujoco_py as non sudoer user
        chmod -R 777 /opt/conda/lib/python3.6/site-packages/mujoco_py/
        pip install --upgrade minerl

# Export global environment variables
%environment
        export SHELL=/bin/sh
        export MUJOCO_PY_MJKEY_PATH=/Gym/.mujoco/mjkey.txt
        export MUJOCO_PY_MUJOCO_PATH=/Gym/.mujoco/mujoco150/
        export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/Gym/.mujoco/mjpro150/bin
        export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/Gym/.mujoco/mujoco200/bin
        export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/bin
        export PATH=/Gym/gym/.tox/py3/bin:$PATH

%runscript
        exec /bin/sh "$@"

Here is the same recipe but written for TensorFlow:

#This is a dockerfile that sets up a full Gym install with test dependencies
Bootstrap: docker

# Here we ll build our container upon the tensorflow container
From: tensorflow/tensorflow:latest-gpu-py3

# Now we'll copy the mjkey file located in the current directory inside the container's root
# directory
%files
        mjkey.txt

# Then we put everything we need to install
%post
        apt -y update && \
        apt install -y keyboard-configuration && \
        apt install -y \
        python3-setuptools \
        python3-dev \
        python-pyglet \
        python3-opengl \
        libjpeg-dev \
        libboost-all-dev \
        libsdl2-dev \
        libosmesa6-dev \
        patchelf \
        ffmpeg \
        xvfb \
        wget \
        git \
        unzip && \
        apt clean && \
        rm -rf /var/lib/apt/lists/*

        # Download Gym and MuJoCo
        mkdir /Gym && cd /Gym
        git clone https://github.com/openai/gym.git || true && \
        mkdir /Gym/.mujoco && cd /Gym/.mujoco
        wget https://www.roboti.us/download/mjpro150_linux.zip  && \
        unzip mjpro150_linux.zip && \
        wget https://www.roboti.us/download/mujoco200_linux.zip && \
        unzip mujoco200_linux.zip && \
        mv mujoco200_linux mujoco200

        # Export global environment variables
        export MUJOCO_PY_MJKEY_PATH=/Gym/.mujoco/mjkey.txt
        export MUJOCO_PY_MUJOCO_PATH=/Gym/.mujoco/mujoco150/
        export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/Gym/.mujoco/mjpro150/bin
        export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/Gym/.mujoco/mujoco200/bin
        export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/bin
        cp /mjkey.txt /Gym/.mujoco/mjkey.txt

        # Install Python dependencies
        wget https://raw.githubusercontent.com/openai/mujoco-py/master/requirements.txt
        pip install -r requirements.txt
        # Install Gym and MuJoCo
        cd /Gym/gym
        pip install -e '.[all]'
        # Change permission to use mujoco_py as non sudoer user
        chmod -R 777 /usr/local/lib/python3.5/dist-packages/mujoco_py/

        # Then install miniworld
        cd /usr/local/
        git clone https://github.com/maximecb/gym-miniworld.git
        cd gym-miniworld
        pip install -e .

# Export global environment variables
%environment
        export SHELL=/bin/bash
        export MUJOCO_PY_MJKEY_PATH=/Gym/.mujoco/mjkey.txt
        export MUJOCO_PY_MUJOCO_PATH=/Gym/.mujoco/mujoco150/
        export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/Gym/.mujoco/mjpro150/bin
        export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/Gym/.mujoco/mujoco200/bin
        export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/bin
        export PATH=/Gym/gym/.tox/py3/bin:$PATH

%runscript
        exec /bin/bash "$@"

Usando Conteiners no cluster

Como usar conteiners no cluster

Em todo cluster com Slurm, os conjuntos de dados e resultados intermediários devem ser armazenados em $SLURM_TMPDIR, enquanto os resultados finais do experimento devem ser salvos em $SCRATCH. Para usar o contêiner que você criou, é necessário copiá-lo para o cluster que deseja usar.

Aviso

Você sempre deve armazenar o seu contêiner em $SCRATCH!

Em seguida, reserve um nó com srun/sbatch, copie o contêiner e o seu conjunto de dados para o nó fornecido pelo SLURM (ou seja, em $SLURM_TMPDIR) e execute o código <YOUR_CODE> dentro do contêiner <YOUR_CONTAINER> com:

singularity exec --nv -H $HOME:/home -B $SLURM_TMPDIR:/dataset/ -B $SLURM_TMPDIR:/tmp_log/ -B $SCRATCH:/final_log/ $SLURM_TMPDIR/<YOUR_CONTAINER> python <YOUR_CODE>

Remember that /dataset, /tmp_log and /final_log were created in the previous section. Now each time, we’ll use singularity, we are explicitly telling it to mount $SLURM_TMPDIR on the cluster’s node in the folder /dataset inside the container with the option -B such that each dataset downloaded by PyTorch in /dataset will be available in $SLURM_TMPDIR.

This will allow us to have code and scripts that are invariant to the cluster environment. The option -H specify what will be the container’s home. For example, if you have your code in $HOME/Project12345/Version35/ you can specify -H $HOME/Project12345/Version35:/home, thus the container will only have access to the code inside Version35.

If you want to run multiple commands inside the container you can use:

Lembre-se de que /dataset, /tmp_log e /final_log foram criados na seção anterior. Agora, cada vez que usarmos o singularity, estamos explicitamente dizendo a ele para montar $SLURM_TMPDIR no nó do cluster na pasta /dataset dentro do container com a opção -B, de modo que cada conjunto de dados baixado pelo PyTorch em /dataset estará disponível em $SLURM_TMPDIR.

Isso nos permitirá ter código e scripts que são invariantes ao ambiente do cluster. A opção -H especifica qual será o diretório raiz do container. Por exemplo, se você tem seu código em $HOME/Projeto12345/Versao35/, você pode especificar -H $HOME/Projeto12345/Versao35:/home, assim o container terá acesso apenas ao código dentro de Versao35.

Se você quiser executar vários comandos dentro do container, pode usar:

singularity exec --nv -H $HOME:/home -B $SLURM_TMPDIR:/dataset/ \
    -B $SLURM_TMPDIR:/tmp_log/ -B $SCRATCH:/final_log/ \
    $SLURM_TMPDIR/<YOUR_CONTAINER> bash -c 'pwd && ls && python <YOUR_CODE>'

Exemplo: Caso interativo (srun/salloc)

Depois de obter uma sessão interativa com o SLURM, copie <YOUR_CONTAINER> e <YOUR_DATASET> para $SLURM_TMPDIR.

# 0. Get an interactive session
$ srun --gres=gpu:1
# 1. Copy your container on the compute node
$ rsync -avz $SCRATCH/<YOUR_CONTAINER> $SLURM_TMPDIR
# 2. Copy your dataset on the compute node
$ rsync -avz $SCRATCH/<YOUR_DATASET> $SLURM_TMPDIR

Então, use o comando singularity shell para obter um shell dentro do contêiner.

# 3. Get a shell in your environment
$ singularity shell --nv \
        -H $HOME:/home \
        -B $SLURM_TMPDIR:/dataset/ \
        -B $SLURM_TMPDIR:/tmp_log/ \
        -B $SCRATCH:/final_log/ \
        $SLURM_TMPDIR/<YOUR_CONTAINER>
# 4. Execute your code
<Singularity_container>$ python <YOUR_CODE>

or use singularity exec to execute <YOUR_CODE>.

# 3. Execute your code
$ singularity exec --nv \
        -H $HOME:/home \
        -B $SLURM_TMPDIR:/dataset/ \
        -B $SLURM_TMPDIR:/tmp_log/ \
        -B $SCRATCH:/final_log/ \
        $SLURM_TMPDIR/<YOUR_CONTAINER> \
        python <YOUR_CODE>

Você também pode criar o seguinte alias para facilitar sua vida:

alias my_env='singularity exec --nv \
        -H $HOME:/home \
        -B $SLURM_TMPDIR:/dataset/ \
        -B $SLURM_TMPDIR:/tmp_log/ \
        -B $SCRATCH:/final_log/ \
        $SLURM_TMPDIR/<YOUR_CONTAINER>'

Isso permitirá que você execute qualquer código com:

my_env python <YOUR_CODE>

Exemplo: caso sbatch

Você também pode criar um script sbatch:

#!/bin/bash
#SBATCH --cpus-per-task=6         # Ask for 6 CPUs
#SBATCH --gres=gpu:1              # Ask for 1 GPU
#SBATCH --mem=10G                 # Ask for 10 GB of RAM
#SBATCH --time=0:10:00            # The job will run for 10 minutes

# 1. Copy your container on the compute node
rsync -avz $SCRATCH/<YOUR_CONTAINER> $SLURM_TMPDIR
# 2. Copy your dataset on the compute node
rsync -avz $SCRATCH/<YOUR_DATASET> $SLURM_TMPDIR
# 3. Executing your code with singularity
singularity exec --nv \
        -H $HOME:/home \
        -B $SLURM_TMPDIR:/dataset/ \
        -B $SLURM_TMPDIR:/tmp_log/ \
        -B $SCRATCH:/final_log/ \
        $SLURM_TMPDIR/<YOUR_CONTAINER> \
        python "<YOUR_CODE>"
# 4. Copy whatever you want to save on $SCRATCH
rsync -avz $SLURM_TMPDIR/<to_save> $SCRATCH

Problema com as bibliotecas PyBullet e OpenGL

Se você estiver executando certos ambientes do gym que requerem o pyglet, você pode encontrar um problema ao executar sua instância do singularity com os drivers Nvidia usando a flag --nv. Isso acontece porque a flag --nv também fornece as bibliotecas do OpenGL:

libGL.so.1 => /.singularity.d/libs/libGL.so.1
libGLX.so.0 => /.singularity.d/libs/libGLX.so.0

Se você não está tendo esses problemas com pyglet, provavelmente não precisa se preocupar com isso. Caso contrário, você pode resolver esses problemas com apt-get install -y libosmesa6-dev mesa-utils mesa-utils-extra libgl1-mesa-glx e, em seguida, certificar-se de que seu LD_LIBRARY_PATH aponte para essas bibliotecas antes das que estão em / .singularity.d / libs.

%environment
        # ...
        export LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu/mesa:$LD_LIBRARY_PATH

Apuana cluster

No cluster Apuana, $SCRATCH ainda não está definido, você deve adicionar os resultados do experimento que deseja manter em /network/scratch/<u>/<username>/. Para usar o script sbatch acima e para corresponder a outros nomes de ambiente de cluster, você pode definir $SCRATCH como um alias para /network/scratch/<u>/<username> com:

echo "export SCRATCH=/network/scratch/${USER:0:1}/$USER" >> ~/.bashrc

Então, você pode seguir o procedimento geral explicado acima.