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.

Paralelización con Gaussian

El CCAR tiene habilitado el software Gaussian para aquellos usuarios que cuenten con una licencia de uso. Para utilizarlo, basta cargar el módulo correspondiente:

$ module load gaussian/g16_2021

Gaussian soporta dos modos de paralelización. En ALICE se encuentra habilitado el soporte multinúcleo, que permite la ejecución en paralelo dentro de un mismo nodo de cálculo. Para ello es necesario, además de hacer la reserva de hilos desde el archivo .job (con #$ -pe smp N), indicarle a Gaussian que debe utilizar los hilos disponibles con alguna de las siguientes directivas:

  • En el archivo de entrada de Gaussian (.gjf), añadiendo la instrucción %CPU=1-N
  • Como parámetro al llamar al ejecutable, con g16 -c="1-N" ...
  • Definiendo la variable de entorno GAUSS_CDEF, añadiendo al archivo .job antes de la llamada a Gaussian export GAUSS_CDEF="1-N"

El uso de -p o $NProcShared está desaconsejado, ya que son instrucciones obsoletas que es posible que desaparezcan en futuras versiones del software. El sitio web de Gaussian dispone de más información sobre todas las opciones de ejecución disponibles.

Confiamos en que estas indicaciones sean útiles para optimizar los cálculos. Recordamos que, para no infrautilizar los recursos disponibles, es necesario que la reserva de hilos de un .job coincida con la carga de trabajo real del software.

Paralelización con R/4.3.1

El clúster ALICE tiene instalada la versión 4.3.1 de R, a disposición de todos sus usuarios. Son varios los paquetes instalados en la suite de R, disponibles utilizando el comando:

> library()

La versión instalada de R tiene soporte nativo para paralelización, tanto en el uso de álgebra lineal a través de BLAS (que utiliza las librerías MKL de Intel Oneapi) como OpenMP. El uso de rutinas de paralelización está ampliamente documentada en la documentacion de R: CRAN Task View: High-Performance and Parallel Computing with R.

Para hacer un uso eficiente de la paralelización de R, es necesario tomar medidas adicionales que no interfieran con el resto de usuarios. Los siguientes códigos de buenas prácticas permiten hacer un buen uso de R en paralelo:

  • Evitar el uso de la librería ‘parallel’, y usar en su lugar la librería ‘parallelly‘, que tiene un soporte más avanzado en las capacidades de paralelización.
  • Sustituir el uso de la función detectCores() por availableCores(), que toma el número de hilos disponibles a partir de la información del job que proporciona el gestor de colas.
  • Usar la librería RhpcBLASctl para especificar el número de hilos de computación, tanto para OpenMP como para BLAS. Esto puede conseguirse con las siguientes instrucciones:
 library('RhpcBLASctl')
 blas_set_num_threads(NCORES)
 omp_set_num_threads(NCORES)

donde NCORES es el número de hilos reservados en el trabajo.

Confiamos en que estas medidas sean útiles para mejorar la eficiencia de los cálculos en R. En cualquiera de los casos, siempre es recomendable hacer un pequeño benchmark para comprobar la combinación más eficiente de hilos que respete, en todo caso, el máximo de la reserva realizada.