Entornos de python

Casper cuenta con un espacio de almacenamiento compartido para los usuarios (el directorio $home) que vive en servidores externos de almacenamiento en red accesibles tanto desde el front-end como desde los nodos de cálculo. El acceso se hace mediante una red dedicada de 10 GbE, que garantiza una alta velocidad pese a la concurrencia de usuarios conectados. Para evitar cuellos de botella, es recomendable hacer un uso razonable de la información del $home, evitando grandes cargas de lectura y escrita desde la red de datos.

Python cuenta con un sistema de instalación de librería muy útil, basado en pip, que permite la instalación de cualquier librería sin más que usar el comando:

$ pip install LIBRERÍA

Al hacer esto, la librería se instala en el directorio $home/.local/lib/python, lo que conlleva una carga de lectura y escritura cada vez que se accede a esa ruta desde los nodos de cálculo. Cuando se lanzan múltiples trabajos en paralelo, se produce una petición masiva a la red de datos, que en casos de librerías pesadas puede sobrecargar la conectividad. Por ese motivo, se establecen los siguientes códigos de buenas prácticas:

Librerías ligeras

Para librerías ligeras y de uso específico o puntual (por ejemplo, sisl), es posible instalar directamente en el $home la librería que se requiera. Para ello, es recomendable abrir una sesión interactiva en un nodo, cargar el módulo de python que corresponda, e instalar la librería con pip. Por ejemplo:

[username@casper] $ qsub -I -q alpha -l walltime=01:00:00
[username@c-0-0] $ module load python-gnu12
[username@c-0-0] $ export PYTHONCACHEPREFIX="/state/partition1/$USER/cache/pycache"
[username@c-0-0] $ export PIP_CACHE_DIR="/state/partition1/$USER/cache/pip-cache"
[username@c-0-0] $ pip3 install --user sisl

Estos comandos instalarán la librería en el directorio $home/.local/lib/pythonX.YY, de modo que queda accesible a todos los nodos usando la red de datos. Una vez instalada la librería, desde el job puede utilizarse añadiendo las instrucciones:

module load python-gnu12
export PYTHONCACHEPREFIX="/state/partition1/$USER/cache/pycache" 
export PIP_CACHE_DIR="/state/partition1/$USER/cache/pip-cache"
python3 -c "import sisl; print('sisl OK')"
python3 script.py

Librerías pesadas

El procedimiento anterior es útil para librerías que funcionan de forma independiente, sin cargar muchas dependencias y que no constituyan un stack completo como Numpy, Scipy, Sci-kit learn, etc. Si se requiere el uso de librerías pesadas o de stacks de desarrollo (o si se necesita una versión específica de python) desaconsejamos la creación de entornos virtuales específicos o la instalación con pip, ya que suponen una sobrecarga considerable de los procesos de lectura y escritura.

Para estos casos es posible solicitar a los administradores la creación de módulos específicos que se instalen en local en los nodos de trabajo, evitando la sobrecarga de la red.

Clúster Casper disponible

Tras meses de trabajo, hemos desplegado completamente el nuevo clúster Casper, que sustituye a Alice. Este nuevo clúster incorpora mejoras significativas tanto de hardware como de software. Por un lado, hemos actualizado el nodo de login (front-end) a un nuevo servidor de altas prestaciones con procesadores de última generación, sustituyendo el anterior que databa de 2008. Todo el sistema de almacenamiento se ha reconstruido con cuatro servidores dedicados (dos de metadatos y dos de almacenamiento) basados en BeeGFS, sobre una red 10 GbE que sustituye a la anterior red de 1 Gb. Se han instalado también dos nuevas redes de comunicación entre nodos para permitir el uso tanto diario como de administración en redes independientes. Hemos actualizado también el hardware de todos los nodos para homogeneizar la infraestructura, incorporando discos NVMe de alta velocidad para el sistema operativo, un sistema de doble scratch SSD y HDD para trabajos con baja o alta demanda de escritura, y al menos 128 GB de RAM en todos los nodos.

En el apartado de software, hemos sustituido toda la infraestructura de Rocks Cluster (basada en Centos 7.4, que databa de 2017) por Rocky Linux, que cuenta con un ciclo de vida hasta 2029. Se ha reestructurado el sistema de gestión del clúster por Warewulf y se ha sustituido el gestor de colas por OpenPBS, integrado todo en la suite OpenHPC. Se han instalado también versiones estables actualizadas tanto de compiladores (libres y propietarios) como del software de investigación disponible.

Los nodos de cálculos existentes en Alice se han migrado satisfactoriamente a Casper, manteniendo las colas de trabajo alpha, beta, gamma, epsilon y dseta. A nivel de administración, la numeración de los nodos se ha modificado para facilitar la identificación nodo-cola y permitir futuras ampliaciones con comodidad.

Las pruebas de rendimiento muestran mejoras de hasta un 40% respecto de Alice, por lo que confiamos en que estas actualizaciones sean de utilidad para todos los investigadores del CCAR.

Logs de salida en Casper

En el clúster Casper, por defecto, los logs de salida (tanto de salida estándar como de error) no se generan en el directorio de trabajo del usuario, sino en el nodo de cálculo en el que se está ejecutando el trabajo. Solo cuando finaliza el trabajo los logs se redirigen al directorio de trabajo, permitiendo que se muestre el contenido tanto de la salida estándar como de la salida de error. Este comportamiento permite minimizar el tráfico entre los nodos de cálculo, mejorando el comportamiento del sistema.

Si es necesario hacer un seguimiento de la evolución de un trabajo, hay dos opciones recomendadas. La primera de ellas consiste en añadir la siguiente directiva en el archivo .job:

#PBS -k oed

Esto hará que los archivos de salida se envíen directamente al directorio de trabajo, sin que se guarden en el nodo de cálculo. Notemos que esta opción puede saturar la red si los logs contienen mucha información que se actualice con frecuencia.

La segunda opción es redirigir la salida estándar de un programa al directorio de trabajo, concatenando con una tubería la ruta a ese directorio:

lmp -in input.lmp -log $PBS_O_WORKDIR/$PBS_JOBID.log
mpirun -np 4 ./ejecutable > $PBS_O_WORKDIR/$PBS_JOBID.log
./ejecutable > $PBS_O_WORKDIR/$PBS_JOBID.log

Cualquiera de estos ejemplos creará en el directorio desde el que se lanza el trabajo ($PBS_O_WORKDIR) un archivo que coincide con el número de trabajo ($PBS_JOBID.log), lo que posibilita ver la evolución del ejecutable. Con relación a la eficiencia, es importante que la salida de los ejecutables no sea continua, sino que se muestre dejando pasar un tiempo razonable entre mensaje y mensaje, de al menos 10 minutos.

En caso de utilizar fortran, es importante desactivar el buffering con la variable de entorno GFORTRAN_UNBUFFERED_ALL dentro del job de trabajo:

export GFORTRAN_UNBUFFERED_ALL=yes 
./ejecutable > $PBS_O_WORKDIR/$PBS_JOBID.log

Independientemente de estas redirecciones, los logs de salida se seguirán generando a partir de la información del job:

# Nombre del log de salida
#PBS -o prueba.out
# Nombre del log de error
#PBS -e prueba.err

Si deseamos que cada job genere un log distinto, basta comentar esas líneas. De este modo, PBS generará automáticamente los siguientes archivos de salida:

$PBS_JOBNAME.o$PBS_JOBID # Archivo de salida estándar
$PBS_JOBNAME.e$PBS_JOBID # Archivo de salida de error