Software de desarrollo instalado¶
El cluster lamb hace uso del sistema de Linux Environment Modules para organizar el software de desarollo instalado en el cluster para que los usuarios puedan compilar y ejecutar sus programas o modelos. Este herramienta llamada Modules permite generar un menú de software para que el usuario seleccione al momento algún paquete.
Uso de módulos¶
Con este sistema se puede modificar de forma dinámica el ambiente de la sesión del usuario, esto con la intención de facilitar el uso de las diferentes herramientas de desarrollo instaladas en lamb.
Note
Por defecto ningún módulo está cargado al iniciar una sesión en el cluster. Todo el software o bibliotecas necesarias para correr sus tareas, deben de ser explicitamente cargadas usando modules para que funcionen correctamente. Si se desea que se cargue un cierto paquete cada vez que se inicie sesión hay que agregar al archivo .bashrc la linea de module load paquete
.
Compiladores Intel y GNU¶
En lamb se cuenta con los compiladores secuenciales y paralelos (MPI) de Intel y los compiladores secuenciales y paralelos (openmpi) de GNU.
intel-tools-2018
intel-tools-2019
oneapi2022
openmpi-4.1-gcc-7.5
Herramientas de CDF (CDFTOOLS,netcdf,cdo..)¶
Se pueden usar las bibliotecas instaladas HDF5, netcdf-c, netcdf-fortran, pnetcdf, cdo, nco, ncview; generadas con los compiladores paralelos de Intel y GNU. Mediante la invocación del mando module:
Para intel (solo usar una a la vez):
module load netcdfIntel2018
module load netcdfIntel2019
netcdfOneAPI2022
Para openmpi:
module load netcdfOpenMPI
Note
Recomendable usar las herramientas de desarrollo de Intel.
Miniforge3 (ipython,conda,mamba)¶
En lamb se encuentran instaladas la versiones 3.9.7 y 3.12.5 de python. Se recomienda el uso de la versión 3.12.5 y se habilita usando el mando: module load miniforge3
.
Se tiene el siguiente código en python. interpol.py
import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from scipy import interpolate
x = np.linspace(0, 10, num=10, endpoint=True)
y = np.cos(-x**2/9.0)
f = interpolate.interp1d(x, y)
f2 = interpolate.interp1d(x, y, kind='cubic')
xnew = np.linspace(0, 10, num=200, endpoint=True)
tck = interpolate.splrep(x, y, s=0)
f3 = interpolate.splev(xnew, tck , der=0)
plt.plot(x, y, 'o', xnew, f(xnew), '-', xnew, f2(xnew), '--', xnew, f3)
plt.title('Intepolacion 1D - metodos')
plt.legend(['data', 'linear', 'cubic','Cubic Spline'], loc='best')
plt.savefig('interpol1D.png', dpi=250, format='png')
Preparamos el script para enviar la tarea al manejador de recursos, por ejemplo interpol.pbs
#!/bin/bash
#PBS -N interpol
#PBS -q intel
#PBS -o interpol.out
#PBS -e interpol.err
#PBS -l nodes=1
# Cambiarse al directorio donde se envio la tarea.
cd $PBS_O_WORKDIR
echo Inicio: `date` > tiempo.log
start=`date +%s`
module load miniforge3
python interpol.py
echo Final : `date` >> tiempo.log
end=`date +%s`
echo Tiempo ejecución : $((end-start)) seg. >> tiempo.log
Para ejecutar la tarea escribimos:
$ qsub interpol.pbs
El resultado de la operación correcta de ésta tarea debe producir dos archivos, una imagen png interpol1D.png
y el archivo tiempo.log
.
Si en caso de que se requiera ciertas versiones de paquetes y de otra versión del intérprete de python, que no coinciden con los instalados en el miniforge, se recomienda la creación personalizada y en su cuenta de un ambiente virtual de python.
Uso de ambientes virtuales¶
Un ambiente virtual es un ambiente personalizado de python con su propio intérprete, bibliotecas y scripts, generados a partir de otro entorno instalado de python. En el caso del cluster se tiene instalado python 3.12 y a partir de éste ambiente se pueden crear ambientes personalizados en su cuenta.
Crear un ambiente virtual en la linea de mandos¶
- Cargar el módulo de python
miniforge3
$ module load miniforge3
- Crear el ambiente virtual.
$ conda create -n test-env python=3.8
Collecting package metadata (current_repodata.json): done
Solving environment: done
## Package Plan ##
environment location: /home/judelga/.conda/envs/test-env
added / updated specs:
- python=3.8
The following packages will be downloaded:
package | build
---------------------------|-----------------
_openmp_mutex-5.1 | 1_gnu 21 KB
ca-certificates-2023.05.30 | h06a4308_0 120 KB
:
:
xz-5.4.2 | h5eee18b_0 642 KB
zlib-1.2.13 | h5eee18b_0 103 KB
------------------------------------------------------------
Total: 51.7 MB
The following NEW packages will be INSTALLED:
_libgcc_mutex pkgs/main/linux-64::_libgcc_mutex-0.1-main
_openmp_mutex pkgs/main/linux-64::_openmp_mutex-5.1-1_gnu
ca-certificates pkgs/main/linux-64::ca-certificates-2023.05.30-h06a4308_0
ld_impl_linux-64 pkgs/main/linux-64::ld_impl_linux-64-2.38-h1181459_1
:
:
pip pkgs/main/linux-64::pip-23.1.2-py38h06a4308_0
python pkgs/main/linux-64::python-3.8.17-h955ad1f_0
readline pkgs/main/linux-64::readline-8.2-h5eee18b_0
setuptools pkgs/main/linux-64::setuptools-67.8.0-py38h06a4308_0
zlib pkgs/main/linux-64::zlib-1.2.13-h5eee18b_0
Proceed ([y]/n)? y
Preparing transaction: done
Verifying transaction: done
Executing transaction: done
#
# To activate this environment, use
#
# $ conda activate test-env
#
# To deactivate an active environment, use
#
# $ conda deactivate
- Activar el ambiente.
$ conda activate test-env
Y se muestra en el prompt el nombre del ambiente entre paréntesis:
(test-env)
- Verificar que haya sido creado el ambiente con:
$ conda env list
test-env * /home/judelga/.conda/envs/test-env
$ conda list
# packages in environment at /home/judelga/.conda/envs/test-env:
#
# Name Version Build Channel
_libgcc_mutex 0.1 conda_forge conda-forge
_openmp_mutex 4.5 2_gnu conda-forge
bzip2 1.0.8 hd590300_5 conda-forge
ca-certificates 2024.6.2 hbcca054_0 conda-forge
ld_impl_linux-64 2.40 hf3520f5_2 conda-forge
libffi 3.4.2 h7f98852_5 conda-forge
libgcc-ng 13.2.0 h77fa898_7 conda-forge
libgomp 13.2.0 h77fa898_7 conda-forge
libnsl 2.0.1 hd590300_0 conda-forge
libsqlite 3.45.3 h2797004_0 conda-forge
libuuid 2.38.1 h0b41bf4_0 conda-forge
libxcrypt 4.4.36 hd590300_1 conda-forge
libzlib 1.3.1 h4ab18f5_1 conda-forge
ncurses 6.5 h59595ed_0 conda-forge
openssl 3.3.1 h4ab18f5_0 conda-forge
pip 24.0 pyhd8ed1ab_0 conda-forge
python 3.8.19 hd12c33a_0_cpython conda-forge
readline 8.2 h8228510_1 conda-forge
setuptools 70.0.0 pyhd8ed1ab_0 conda-forge
tk 8.6.13 noxft_h4845f30_101 conda-forge
wheel 0.43.0 pyhd8ed1ab_1 conda-forge
xz 5.2.6 h166bdaf_0 conda-forge
Crear un ambiente virtual a partir de un archivo yaml¶
Un archivo .yml es un archivo de texto que contiene una lista de dependencias de paquetes que se instalarán dentro del ambiente virtual.
PASOS.
- Crear un archivo de configuración en formato
yaml
o bien usar algun archivo preexistente comoenvironment.yml
de algun paquete en python. Por ejemplo para el software GLMTools se requiere el siguiente ambiente de desarrollo.
name: glmval
channels:
- conda-forge
- defaults
dependencies:
- hdf5
- netcdf4
- numpy
- pandas
- pip
- pyclipper
- python=3.6
- scipy
- xarray
- pip:
- git+https://github.com/deeplycloudy/lmatools.git
- git+https://github.com/deeplycloudy/stormdrain.git
La primera linea del archivo yaml debe tener el nombre del nuevo ambiente. En este caso el ambiente se llamará glmval
- Se procede a crear el ambiente con:
$ conda env create -f environment.yml
- Verificar que haya sido creado el ambiente llamado
glmval
con:
$ conda env list
# conda environments:
#
base /opt/miniforge3
copernicusmarine /opt/miniforge3/envs/copernicusmarine
glmval /home/judelga/.conda/envs/glmval
test-env * /home/judelga/.conda/envs/test-env
Mandos útiles de ambientes virtuales en python¶
- Para crear un ambiente virtual de python con algunos paquetes en especifico.
$ conda create -n myenv scipy numpy python=3.6
$ conda create --name myenv jupyterlab=3.2 matplotlib=3.5 numpy=1.21
- Para instalar un paquete en un ambiente virtual por ejemplo numba en myenv:
$ conda activate myenv
(myenv)$ conda install numba
## Package Plan ##
environment location: /home/computo/.conda/envs/myenv
added / updated specs:
- numba
The following NEW packages will be INSTALLED:
libllvm10 pkgs/main/linux-64::libllvm10-10.0.1-hbcb73fb_5
llvmlite pkgs/main/linux-64::llvmlite-0.36.0-py36h612dafd_4
numba pkgs/main/linux-64::numba-0.53.1-py36ha9443f7_0
tbb pkgs/main/linux-64::tbb-2020.3-hfd86e86_0
- Listar los ambientes instalados.
$ conda env list
- Listar los paquetes instalados de un ambiente virtual.
$ conda list -n myenv
- Activar un ambiente virtual de python.
$ conda activate test-env
- Desactivar el ambiente actual cargado.
(test-env) $ conda deactivate
- Borrar un ambiente virtual.
$ conda remove --name myenv --all
JupyterLab¶
Con Jupyter Notebook y JupyterLab se pueden ejecutar comandos de Python o Julia desde una interface web. Estos comandos se ejecutan en los recursos reservados de lamb, y se reciben los resultados numéricos o gráficos, embebidos en la misma interface web.
Jupyter Notebook v7.2.2 y JupyterLab v4.2.5 está disponibe a través de la carga del módulo miniforge3.
Pasos:
- Tomar un nodo de cómputo para ejecutar jupyter notebook, esto mediante la realización de un script PBS.
notebook-job.pbs
#!/bin/bash
#PBS -N notebook-job
#PBS -l nodes=1,walltime=01:00:00
#PBS -q intel
#PBS -o notebook-job.out
#PBS -e notebook-job.err
cd $PBS_O_WORKDIR
module load miniforge3
JUPYTERPORT=9999
echo "ssh -N -L $JUPYTERPORT:$(hostname):$JUPYTERPORT $USER@lamb.cicese.mx"
jupyter notebook --no-browser --ip=$(hostname) --port=$JUPYTERPORT --NotebookApp.token=''
- Enviar el script:
% qsub notebook-job.pbs
- Revisar el contenido del archivo
notebook-job.out
. En la primera linea de este archivo estará un comando de ssh que se necesita ejecutar en nuestro equipo local (PC, Laptop). El mando será algo como lo siguiente:
ssh -N -L 9999:node17:9999 miusuario@lamb.cicese.mx
- Copiar este mando y ejecutarlo en una sesión en el equipo local, ssh preguntará por su contraseña de acceso a lamb. Una vez escrita se puede abrir el navegador (firefox, chrome) y teclear
http://localhost:9999
para ejecutar el dashboard o interface web de jupyter notebook, y conhttp://localhost:9999/lab
se puede ingresar a JupyterLab.
Tambien se puede acceder a JupyterLab desde la sección View
y Open JupyterLab
de la interface de jupyter notebook.
- Una vez finalizado de usar el jupyter notebook o jupyterlab cerrar toda la conexión mediante el dashboard seleccionando
Shut Down
de la sección deFile
de cada interface o abortar la conexión ssh que se abrió en su equipo local y eliminar la tarea del PBS conqdel
en lamb.
Mandos utiles de modules¶
$ module avail
---------------------------- /usr/share/Modules/modulefiles -----------------------------
anaconda-python-3.9 debugger/latest gcc-9.4.0 matlab-R2017b netcdfOneAPI2022 seacasProject
cmake-3.18-gnu dot gmt-6.2.0 matlab-R2023b netcdfOpenMPI tbb/2021.7.1
compiler/2022.2.1 dpl/2021.7.2 icc/2022.2.1 miniforge3 mpi/2021.7.1 textlive
compiler/latest dpl/latest icc/latest mkl/2022.2.1 mpi/latest oneapi2022
compiler-rt/2022.2.1 gcc-7.5.0 intel-tools-2018 mkl/latest netcdfIntel2018 openmpi-4.1-gcc-7.5
debugger/2021.7.1 gcc-7.5.0-spack intel-tools-2019 module-git netcdfIntel2019 R-4.1.1
$ module load oneapi2022
$ module list
Currently Loaded Modulefiles:
1) miniforge3 3) icc/2022.2.1 5) mkl/2022.2.1 7) compiler/2022.2.1
2) compiler-rt/2022.2.1 4) tbb/2021.7.1 6) mpi/2021.7.1 8) oneapi2022
$ module display oneapi2022
-------------------------------------------------------------------
/usr/share/Modules/modulefiles/oneapi2022:
module-whatis Compilador intel 2021 (MPI+MKL)
conflict intel-tools-2019
module load icc/2022.2.1
module load mkl/2022.2.1
module load mpi/2021.7.1
module load compiler/2022.2.1
module load compiler-rt/2022.2.1
module load tbb/2021.7.1
-------------------------------------------------------------------
Matlab¶
¿Que versión de matlab esta disponible?¶
En lamb se encuentra instalada la versión R2017b y R2023b de matlab, si se desea usar el matlab 2023b se tendra que cargar el módulo con:
$ module load matlab-R2023b
¿Como ejecuto MATLAB?¶
Warning
Hay que asegurarnos que ejecutar MATLAB en un nodo de cómputo y no en el nodo maestro lamb
.
Es posible asi utilizar todos los cores de un nodo sin ninguna configuración especial. (Aunque es posible definir desde qsub cuantos cores pretendemos utilizar).
Ejecutar MATLAB interactivamente:¶
Para ejecutar Matlab interactivamente, necesitamos crear una sesión interactiva en un nodo de cómputo. Para hacer esto en lamb solicitamos la sesión con 1 nodo de cómputo, con el siguiente comando:
$ qsub -X -I -l nodes=1,walltime=24:00 -q intel -d $PWD
qsub: waiting for job 12788 to start
qsub: job 12788 ready
$ _
Una vez que la sesión interactiva comience, podemos cargar los módulos apropiados y empezar Matlab como se describe a continuación:
$ module load matlab-R2023b
$ matlab -nodisplay -nosplash -r "miScript ; exit" < /dev/null > matrun.out 2> matrun.err
Este comando ejecutará los contenidos de miScript.m, enviando la salida de consola al archivo matrun.out
y los mensajes de error a matrun.err
.
También es posible tener una sesión interactiva de matlab, solo limitados en cuanto a la visualización de gráficos.
$ module load matlab-R2023b
$ matlab -nodisplay -nosplash
< M A T L A B (R) >
Copyright 1984-2023 The MathWorks, Inc.
R2023b (23.2.0.2365128) 64-bit (glnxa64)
August 23, 2023
To get started, type one of these: helpwin, helpdesk, or demo.
For product information, visit www.mathworks.com.
>>
Ejecución de MATLAB por lotes (paralelo)¶
Se cuenta con licencias del toolbox Parallel Computing de matlab, con esto se puede paralelizar ciclos de matlab en varios cores de un nodo de procesamiento, se usan los llamados workers
para lograr esto. Los workers
son procesos de MATLAB que se ejecutan en segundo plano sin un escritorio gráfico.
Suponiendo que tenemos el siguiente código de matlab. Una función programada en stiffODEfun.m
function dy = stiffODEfun(t,y,c)
% This is a modified example from MATLAB's documentation at:
% http://www.mathworks.com/help/matlab/ref/ode15s.html
% The difference here is that the coefficient c is passed as an argument.
dy = zeros(2,1);
dy(1) = y(2);
dy(2) = c*(1 - y(1)^2)*y(2) - y(1);
end
Y el programa principal de matlab stiffODE.m
con un ciclo paralelizado con parfor
%{
This script samples a parameter of a stiff ODE and solves it both in
serial and parallel (via parfor), comparing both the run times and the
max absolute values of the computed solutions. The code -- especially the
serial part -- will take several minutes to run on Eagle.
%}
% open the local cluster profile
%p = parcluster('local');
% open the parallel pool, recording the time it takes
time_pool = tic;
parpool(10);
time_pool = toc(time_pool);
fprintf('Opening the parallel pool took %g seconds.\n', time_pool)
% create vector of random coefficients on the interval [975,1050]
nsamples = 100; % number of samples
coef = 975 + 50*rand(nsamples,1); % randomly generated coefficients
% compute solutions within serial loop
time_ser = tic;
y_ser = cell(nsamples,1); % cell to save the serial solutions
for i = 1:nsamples
if mod(i,10)==0
fprintf('Serial for loop, i = %d\n', i);
end
[~,y_ser{i}] = ode15s(@(t,y) stiffODEfun(t,y,coef(i)) ,[0 10000],[2 0]);
end
time_ser = toc(time_ser);
% compute solutions within parfor
time_parfor = tic;
y_par = cell(nsamples,1); % cell to save the parallel solutions
err = zeros(nsamples,1); % vector of errors between serial and parallel solutions
parfor i = 1:nsamples
if mod(i,10)==0
fprintf('Parfor loop, i = %d\n', i);
end
[~,y_par{i}] = ode15s(@(t,y) stiffODEfun(t,y,coef(i)) ,[0 10000],[2 0]);
err(i) = norm(y_par{i}-y_ser{i}); % error between serial and parallel solutions
end
time_parfor = toc(time_parfor);
time_par = time_parfor;
% print results
fprintf('RESULTS\n\n')
fprintf('Serial time : %g\n', time_ser)
fprintf('Parfor time : %g\n', time_par)
fprintf('Speedup : %g\n\n', time_ser/time_par)
fprintf('Max error between serial and parallel solutions = %e\n', max(abs(err)))
% close the parallel pool
delete(gcp)
exit
Para ejecutarlo en uno de los nodos de procesamiento se necesita crear un script de PBS. En este caso estamos paralelizando el ciclo for
de matlab con 10 workers, el script de PBS queda:
Ejemplo : worker.pbs
#!/bin/bash
## Directivas
#PBS -N worker
#PBS -p intel
#PBS -o worker.out
#PBS -e worker.err
#PBS -l nodes=1:ppn=10
# Cambiarse al directorio donde se envio la tarea.
cd $PBS_O_WORKDIR
module load matlab-R2023b
matlab -nosplash -nodisplay -nodesktop -r "stiffODE; exit;"
Para enviar la tarea al manejador de colas se ejecuta:
$ qsub worker.pbs
Se revisa el archivo worker.out
una vez que termine la ejecución.
$ cat worker.out
Starting parallel pool (parpool) using the 'Processes' profile ...
Connected to parallel pool with 10 workers.
Opening the parallel pool took 15.5551 seconds.
Serial for loop, i = 10
Serial for loop, i = 20
Serial for loop, i = 30
Serial for loop, i = 40
Serial for loop, i = 50
Serial for loop, i = 60
Serial for loop, i = 70
Serial for loop, i = 80
Serial for loop, i = 90
Serial for loop, i = 100
Parfor loop, i = 50
Parfor loop, i = 10
Parfor loop, i = 30
Parfor loop, i = 20
Parfor loop, i = 70
Parfor loop, i = 40
Parfor loop, i = 80
Parfor loop, i = 60
Parfor loop, i = 90
Parfor loop, i = 100
RESULTS
Serial time : 3.66127
Parfor time : 1.32643
Speedup : 2.76024
Max error between serial and parallel solutions = 0.000000e+00
Parallel pool using the 'Processes' profile is shutting down.