Skip to the content.

Hay muchos aspectos interesantes que quedaron sin mencionar. Aquí un rápido resumen:

Librerías interesantes

En Julia Packages se puede buscar entre todos los paquetes registrados de Julia. Sin embargo, también hay paquetes no registrados, subidos a github. Para instalarlos, basta poner, en una consola: ] add seguido de la dirección al repositorio. Mencionamos algunos ejemplos:

Álgebra Lineal

Gráficos

Si bien Plots.jl es la librería estándar para dibujar, hay varios paquetes que hacen uso de librerías externas o agregan ciertas funcionalidades.

Ecuaciones diferenciales

Análisis de datos

Imágenes

Procesamiento de señales

Cálculo simbólico

Álgebra

Geometría Algebraica

Notebooks

Debug y control de código.

Paralelización

Julia integra el cálculo en paralelo desde su núcleo y además se presta facilmente al uso de GPU.

Programación asincrónica

Se puede suspender programáticamente la ejecución de código, a la espera de concretar otras tareas. Por ejemplo: se puede hacer un programa que inicie ciertas operaciones, lance la descarga de un archivo de internet, realice otras operaciones en paralelo y retome el trabajo una vez que la descarga haya finalizado. Véase la Documentación.

Threads

Iniciando Julia con el comando julia --threads 4, si inicia una sesión de la consola con 4 threads disponibles (si el CPU lo admite). Luego usando el macro Threads.@threads se puede, por ejemplo, paralelizar un for. Sin embargo, hay que tener mucho cuidado para evitar que los distintos threads operen sobre las mismas variables, porque pueden sobreescribirse unos a otros y ocasionar resultados inesperados. Véase la Documentación

GPU

JuliaGPU es un proyecto que incluye los cuatro grandes paquetes que permiten paralelizar usando GPUs. Hay un paquete especializado para cada una de las tecnologías disponibles:

Se encuentran en distinto nivel de desarrollo. La más completa es CUDA.jl, pero AMDGPU.jl y Metal.jl están perfectamente operativas.

Creación de paquetes propios

En Julia crear un paquete propio es realmente muy sencillo. Basta crear un directorio para contenerlo, abrir una consola de Julia dentro del directorio y tipear:

  pkg> generate NombreDelPaquete

Esto creará todos los archivos necesarios para definir el paquete. En particular, creará una carpeta /src y dentro de ella un archivo NombreDelPaquete.jl. Dentro de este archivo tendremos la definición del módulo:

module NombreDelPaquete

end;

Esencialmente se trata escribir todo el código necesario en nuevos archivos .jl, incluyendo los nuevos tipos que se definan y las funciones. Luego, en NombreDelPaquete, dentro de la definición del módulo agregamos:

Si en una consola nos ubicamos en el directorio del paquete y tipeamos:

  pkg> activate .

Entraremos en el entorno del propio paquete. Si ahora hacemos, por ejemplo:

  pkg> add Plots

esto agregará Plots como dependencia de nuestro paquete. Con este sólo paso conseguimos:

Si subimos nuestro paquete a un repositorio de Github, será instalable por cualquier usuario mediante la dirección del repositorio. Si además lo registramos en JuliaPackages, podrá instalarse con

  pkg> add NombreDelPaquete

Además, hay herramientas que permiten automatizar la creación de documentación y muchos más chiches.

Metaprogramación

El código Julia es un objeto dentro de Julia. Es decir que un fragmento de código puede ser tomado como una expresión dentro del lenguaje y ejecutado. Por ejemplo:

  julia> e = :(x=2; x+3)
  julia> typeof(e)
  julia> eval(e)

e es una expresión que puede evaluarse, lo que equivale a correr el código definido dentro de ella.

Los macros de Julia (toda sentencia con prefijo @, como @time, @benchmark, @animate, etc.) convierten en expresión el código que uno les pasa, agregan otras expresiones y ejecutan el código resultante. Es decir: al correr un macro Julia está creando código nuevo sobre el nuestro y lo está ejecutando. A esto se lo llama metaprogramación.

Ya observamos que los macros agregan gran funcionalidad permitiendo ejecutar procesos complejos con un simple prefijo. Cualquier usuario puede definir nuevos macros. El macro @macroexpand permite ver qué código genera otro macro.

Performance

Ya vimos que Julia es realmente rápido. Sin embargo, la velocidad intrínseca puede empeorar con una mal código. Si se quiere código veloz, es importante tener en mente los Consejos de Performance. En particular, hay dos puntos muy importantes:

Introspección

Julia brinda muchas herramientas para investigar nuestro propio código. Por ejemplo al usar el macro @code_warntype como prefijo a la ejecución de una función nos advertirá si en algún lugar de nuestro código el compilador se encuentra con problemas para decidir el tipo de una variable. Esto nos permite corregir la ambiguedad y acelerar el código.

Además, la conversión de nuestro código a lenguaje de máquina se realiza en varios pasos. Hay funciones y macros que nos permiten ver el resultado de cada paso. Meta.@lower nos da el primer paso de traducción. Es decir: la conversión de nuestro código en expresiones de Julia. Ya mencionamos @code_warntype para ver nuestro código con tipos. Luego @code_llvm nos da la traducción de nuestro código luego de pasar por LLVM (que es lo que usa Julia para compilar). Finalmente @code_native nos muestra en código en lenguaje de máquina.


<< Volver a la primera parte