Loading...
 

R en el clúster

En este taller veremos una pequeña introducción al sistema de colas y un ejemplo de ejecución de un script en R simultáneamente en los diferentes nodos del clúster para hacer un análisis de datos sencillo.

Para ingresar al clúster desde una máquina windows puede revisar el tutorial:
http://clusteri.itm.edu.co/wiki/tiki-index.php?page=Acceso+windows
O desde una máquina tipo unix (linux/mac)
http://clusteri.itm.edu.co/wiki/tiki-index.php?page=Acceso+linux

Una introducción al sistema de colas que usamos en el clúster la puede encontrar en: http://clusteri.itm.edu.co/wiki/tiki-index.php?page=Tutorial+TorquePBS
El primer script que vamos a realizar nos permitirá revisar que los procesos se realizan en algún nodo de trabajo (wn#) y los registros de ejecución en el sistema de colas. El siguiente código usa el comando de linux echo para imprimir en pantalla el nombre del nodo enq ue se está ejecutando y el coando sleep que en nuestro caso esperará 60 segundos antes de terminar. La opción de PBS -N es el nombre que le daremos a la tarea:

#!/bin/bash
#PBS -N mitrabajo	

echo $(hostname)
sleep 60


Puedo llamar este archivo sleep.job y lanzo la tarea con

qsub sleep.job


Para mirar si el proceso está corriendo podemos ejecutar un par de comandos:

qstat -a
showq


Cuando termine la ejecución, si ocurrió algún error podremos observarlos en los archivos de salida de error (.e); y si todo se ejecutó correctamente veremos en archivos de salida (.o) el nombre del nodo en el que se ejecutó nuestra tarea. Lo podemos hacer con el comando:

cat mitrabajo.o####

Donde #### es un número de identificación de la tarea lanzada.

Ahora usaremos algunas variables de pBS útiles para nuestro código en R. EN el siguiente script de ejecución tenemos dos líneas #PBS adicionales al anterior.
La opción -l walltime=1:00:00 indica que nuestro programa tiene un máximo de duración de 1 hora. Si la ejecución alcanza este tiempo será terminada. Esto nos puede servir para evitar errores como ciclos infinitos o divergencias en los cálculos.
La opción -t nos va a facilitar el uso de una lista de valores que se especifican en el argumento siguiente, en este caso 21-24 indica que usaremos los números del 21 al 24 (inclusive) dentro de la variable $PBS_ARRAYID.
Esta última variable la usaremos en el comando head -n 1 que nos permite imprimir en la terminal el primer renglón del archivo que se encuentra en /share1/gerardo/datosR/data_$PBS_ARRAYID

#!/bin/bash
#PBS -N myArrayjob
#PBS -l walltime=1:00:00
#PBS -t 21-24

#echo $PBS_ARRAYID
head -n 1  /share1/gerardo/datosR/data_$PBS_ARRAYID

Una vez ejecutado el código, podemos monitorearlo con showq y revisar los registros de error y de salida.

El siguiente código tomará un conjunto de archivos que contienen tweets y va a contar las ocurrencias de las palabras que allí se encuentran. En este caso debemos adaptar el procedimiento para que se ejecute correctamente en nuestro sistema de colas. Para esto hemos definido dos variables que se ingresan por línea de comandos: La ruta de nuestra carpeta de trabajo y un índice del archivo a leer que corresponderá también al archivo que se va a escribir con los resultados.
(para este código debemos crear una carpeta llamada output en nuestro directorio de trabajo)

library(SnowballC)
library(tm)
library(stringi)

args = commandArgs(trailingOnly=TRUE)
path=paste(args[1],"/output/output",sep="")
input_filename=paste("/share1/gerardo/datosR/data_",args[2],sep="")
output_filename=paste(path,args[2],sep="")

print(input_filename)
print(output_filename)

texto=readChar(input_filename,file.info(input_filename)$size)

print("Limpiando los datos")
#Limpiar los datos
texto<-iconv(texto, to="ASCII//TRANSLIT",sub="")

documento <- Corpus(VectorSource(texto))
preposiciones<-c("a","ante","bajo", "cabe","con","contra","de","desde","en","entre","hacia","hasta","para","por","segun","sin","so","sobre","tras")
preguntas<-c("que","cuando","porque","quien","cual","donde")
twitter<-c("rt")
#pasar todo a minúscula
documento <- tm_map(documento, content_transformer(tolower))
#quitar los números
documento <- tm_map(documento, removeNumbers)
#quitar los signos de puntuación
documento <- tm_map(documento, removePunctuation)
#quitar las preguntas
documento <- tm_map(documento, removeWords,preguntas)
#quitar las preposiciones
documento <- tm_map(documento, removeWords,preposiciones)
#quitamos cosas de twitter
documento <- tm_map(documento, removeWords,twitter)
#quitar otras palabras inservibles
documento <- tm_map(documento, removeWords,stopwords("spanish"))
documento <- tm_map(documento, removeWords,stopwords("english"))
#dejar sólo un espacio en blanco entre palabras
documento <- tm_map(documento, stripWhitespace)

print("Creando dataframe de conteo")
#Creamos la matriz de conteo 
terminos <- as.matrix(TermDocumentMatrix(documento))
ordenados <- sort(rowSums(terminos),decreasing=TRUE)
df <- data.frame(word = names(ordenados),freq=ordenados)
print("Muestra de los primeros 10 datos")
print(df[0:10,])
print("Guardando archivo")
write.csv(df,output_filename)


Para nuestro script de ejecución incluimos una nueva variable $PBS_O_WORKDIR que referencia a la ruta en la que lanzamos la tarea. Esta misma ruta es donde guardamos el script de ejecución, el código en R (que llamamos wordcount.R) y la carpeta (output) donde guardamos los resultados.

#!/bin/bash
#PBS -N wordcountJob
#PBS -l walltime=1:00:00
#PBS -t 10-19

Rscript $PBS_O_WORKDIR/wordcount.R $PBS_O_WORKDIR $PBS_ARRAYID


A este script lo llamo wordcount.job y recordemos lanzarlo con

qsub wordcount.job


Para conocer más sobre las opciones de torque pbs puede ir a los siguientes tutoriales:
https://oit.colorado.edu/tutorial/managed-services-how-use-torque
https://hpcc.usc.edu/support/documentation/useful-pbs-commands/