Julia, à ce stade (mai 2019, Julia v1.1 dont la v1.2 est sur le point de sortir) est assez mature pour le calcul scientifique. La version 1.0 signifiait la fin des ruptures de code annuelles . Avec cela, beaucoup de bibliothèques informatiques scientifiques ont eu le temps de simplement se développer sans interruption. Un large aperçu des paquets de Julia peut être trouvé à pkg.julialang.org .
Pour le calcul scientifique de base, la bibliothèque DifferentialEquations.jl pour les équations différentielles (ODE, SDE, DAE, DDE, simulations de Gillespie, etc.), Flux.jl pour les réseaux de neurones et la bibliothèque JuMP pour la programmation mathématique (optimisation: linéaire, quadratique, mixte, etc.) sont trois des pierres angulaires de l’écosystème de l’informatique scientifique. La bibliothèque d'équations différentielles en particulier est beaucoup plus développé que ce que vous verriez dans d' autres langues, avec une grande équipe de développement mise en œuvre de fonctionnalités telles que les intégrateurs EPIRK , Runge-Kutta-Nystrom , équation différentielle Stiff / retard différentiel-Algébrique etLes intégrateurs d’ équations différentielles stochastiques rigides adaptables au temps , ainsi que de nombreux autres avantages tels que l’ analyse de sensibilité adjointe , les DSL à réaction chimique , la matrice de Newton-Krylov sans matrice et la compatibilité GPU complète (sans transfert de données), avec la formation aux équations différentielles neuronales , le tout avec résultats de référence fantastiques (disclaimer: je suis le développeur principal).
Ce qui est un peu ahurissant à propos de l’écosystème mûr de Julia, c’est sa composition. Essentiellement, lorsque quelqu'un crée une fonction de bibliothèque générique comme celle de DifferentialEquations.jl, vous pouvez utiliser n'importe quel type AbstractArray / Number pour générer du nouveau code à la volée. Ainsi, par exemple, il existe une bibliothèque pour la propagation des erreurs ( Measurements.jl ). Lorsque vous la collez dans le solveur ODE, elle compile automatiquement une nouvelle version du solveur ODE qui effectue la propagation des erreurs sans échantillonnage de paramètres . De ce fait, il est possible que certaines fonctionnalités ne soient pas documentées car le code de ces fonctionnalités est généré automatiquement. Vous devez donc réfléchir davantage à la composition de la bibliothèque.
L'algèbre linéaire est l'un des domaines où la composition est la plus utile. Les solveurs ODE, par exemple, vous permettent de spécifier jac_prototype
, vous permettant de lui donner le type du jacobien qui sera utilisé en interne. Bien sûr, il existe des éléments dans la bibliothèque standard LineraAlgebra tels Symmetric
que Tridiagonal
vous pouvez les utiliser ici, mais étant donné l’utilité de la composibilité dans les algorithmes de type générique, les utilisateurs n’ont désormais plus créé de bibliothèques de types de tableaux. BandedMatrices.jl et BlockBandedMatrices.jl sont des bibliothèques qui définissent des types de matrices à bandes (Block) avec des lu
surcharges rapides , ce qui en fait un moyen agréable d’accélérer la solution des discrétisations MOL rigides de systèmes d’équations aux dérivées partielles. PDMats.jlpermet la spécification de matrices définies positives. Elemental.jl vous permet de définir un jacobien distribué et fragmenté. CuArrays.jl définit les tableaux sur le GPU. Etc.
Ensuite, vous avez tous vos types de numéro. Unitful.jl vérifie les unités au moment de la compilation, c'est donc une bibliothèque d'unités sans surcoût. DoubleFloats.jl est une bibliothèque rapide de haute précision, avec Quadmath.jl et ArbFloats.jl . ForwardDiff.jl est une bibliothèque pour la différenciation automatique en mode avant qui utilise l'arithmétique à deux chiffres. Et je peux continuer à les lister. Et oui, vous pouvez les jeter dans des bibliothèques Julia suffisamment génériques, telles que DifferentialEquations.jl, pour compiler une version spécialement optimisée pour ces types de nombres. Même quelque chose comme ApproxFun.jlqui fonctionne comme des objets algébriques (comme Chebfun) fonctionne avec ce système générique, permettant de spécifier des PDE comme ODE sur des scalaires dans un espace fonctionnel.
Compte tenu des avantages de la composibilité et de la manière dont les types peuvent être utilisés pour générer un code nouveau et efficace sur les fonctions génériques de Julia, de nombreux efforts ont été déployés pour intégrer la mise en œuvre des fonctionnalités de calcul scientifique de base à Julia. Optim.jl pour l'optimisation non linéaire, NLsolve.jl pour la résolution de systèmes non linéaires, IterativeSolvers.jl pour les solveurs itératifs de systèmes linéaires et de systèmes de systèmes électroniques, BlackBoxOptim.jl pour l'optimisation par boîte noire, etc. Même la bibliothèque de réseaux neuronaux Flux.jl utilise simplement CuArrays. La compilation automatique de code par jl sur le GPU pour ses capacités de GPU. Cette composibilité était au cœur de ce qui créait des choses comme les équations différentielles neurales dans DiffEqFlux.jl. Les langages de programmation probabilistes tels que Turing.jl sont également bien matures et utilisent les mêmes outils sous-jacents.
Étant donné que les bibliothèques de Julia reposent fondamentalement sur des outils de génération de code, il ne faut pas s'étonner qu'il y ait beaucoup d'outils autour de la génération de code. Le système de diffusion de Julia génère des noyaux fusionnés à la volée qui sont surchargés par des types de matrice pour donner un grand nombre des fonctionnalités mentionnées ci-dessus. CUDAnative.jl permet de compiler le code de Julia dans les noyaux GPU. ModelingToolkit.jl convertit automatiquement les AST en un système symbolique de transformation du code mathématique. Cassette.jlvous permet de "superposer" la fonction existante de quelqu'un d'autre, en utilisant des règles pour modifier sa fonction avant la compilation (par exemple: modifier toutes ses allocations de tableau en attributions de tableau statiques et déplacer des opérations vers le GPU). C'est un outil plus avancé (je ne m'attends pas à ce que tout le monde en informatique scientifique prenne le contrôle direct du compilateur), mais c'est ainsi que sont construits une grande partie de l'outillage de la prochaine génération (ou plutôt, comment les entités écrivent elles-mêmes).
En ce qui concerne le parallélisme, j'ai mentionné les GPU, et Julia a le multithreading intégré et l'informatique distribuée . Le multithreading de Julia utilisera très bientôt une architecture PARTR (tâches parallèles) qui permet la planification automatisée du multithreading imbriqué . Si vous souhaitez utiliser MPI, vous pouvez simplement utiliser MPI.jl . Et bien sûr, le moyen le plus simple de tirer parti de tout cela consiste simplement à utiliser une configuration de type AbstractArray pour utiliser le parallélisme dans ses opérations.
Julia possède également l'écosystème sous-jacent de base d'un langage à usage général utilisé pour des applications scientifiques. Il a l' EDI Juno avec un débogueur intégré avec des points d'arrêt , il a Plots.jl pour faire toutes sortes de tracés. De nombreux outils spécifiques sont également utiles , comme Revise.jl met automatiquement à jour vos fonctions / bibliothèque lors de la sauvegarde d’un fichier. Vous avez votre DataFrames.jl , vos bibliothèques de statistiques , etc. L’une des bibliothèques les plus agréables est Distributions.jl, qui vous permet d’écrire des algorithmes génériques pour la distribution (par exemple:rand(dist)
prend un nombre aléatoire de la distribution qui a été passée), et il y a tout un tas de distributions univariées et multivariées (et bien sûr, la distribution a lieu au moment de la compilation, ce qui rend tout cela aussi rapide que le codage en dur d’une fonction spécifique à la distribution). Il existe de nombreux outils de traitement de données , serveurs Web , etc. À ce stade, il est suffisamment mature pour que s’il existe un élément scientifique de base et que vous vous attendiez à ce qu’il existe, il vous suffit de le rechercher dans le fichier .jl ou Julia.
Ensuite, il y a quelques choses à garder à l'esprit à l'horizon. PackageCompiler cherche à créer des fichiers binaires à partir de bibliothèques Julia. Il a déjà eu quelques succès, mais nécessite davantage de développement. Makie.jl est une bibliothèque complète pour le traçage avec interactivité accélérée par GPU. Il reste encore du travail à faire, mais elle cherche vraiment à devenir la principale bibliothèque de traçage de Julia. Zygote.jl est une bibliothèque de différenciation automatique source à source qui ne présente pas les problèmes de performances d'une AD basée sur le traçage (Tracker, PyTorch, Jax), et qui cherche à fonctionner avec tous les codes purs de Julia. Etc.
En conclusion, vous pouvez trouver beaucoup de mouvement dans beaucoup d'endroits, mais dans la plupart des endroits, il existe déjà une bibliothèque solide et mûrie. Ce n'est plus à un endroit où vous demandez "sera-t-il adopté?": Julia a été adoptée par suffisamment de personnes (des millions de téléchargements) pour rester sur la lancée. Il a une communauté vraiment sympa, donc si vous voulez juste prendre des clichés et parler de calcul parallèle ou d'équations différentielles numériques, quelques-unes des meilleures salles de discussion à ce sujet figurent dans le Julialang Slack . Savoir si c'est une langue que vous devriez apprendre est une question personnelle, et si c'est la bonne langue pour votre projet, c'est une question technique, et celles-ci sont différentes. Mais est-ce un langage qui a mûri et qui est soutenu par un grand groupe cohérent de développeurs? Cela semble être un oui affirmatif.