Julia, neste momento (maio de 2019, Julia v1.1 com v1.2 prestes a sair) é bastante madura para a computação científica. A versão v1.0 significava o fim da quebra anual de código . Com isso, muitas bibliotecas de computação científica tiveram tempo de simplesmente crescer sem interrupções. Uma ampla visão geral dos pacotes Julia pode ser encontrada em pkg.julialang.org .
Para a computação científica central, a biblioteca DifferentialEquations.jl para equações diferenciais (ODEs, SDEs, DAEs, DDEs, simulações de Gillespie etc.), Flux.jl para redes neurais e a biblioteca JuMP para programação matemática (otimização: linear, quadrática, número inteiro misto, etc.) são três dos pilares do ecossistema de computação científica. A biblioteca de equações diferenciais, em particular, é muito mais desenvolvida do que o que você veria em outros idiomas, com uma grande equipe de desenvolvimento implementando recursos como integradores EPIRK , Runge-Kutta-Nystrom , equação diferencial de atraso rígido / diferencial-algébrico eintegradores de equações diferenciais estocásticas rígidas e adaptáveis , juntamente com vários outros itens, como análise de sensibilidade adjunta , DSLs de reação química , Newton-Krylov sem matriz e compatibilidade GPU completa (sem transferência de dados), com treinamento de equações diferenciais neurais , tudo com resultados fantásticos de benchmark (aviso: sou o desenvolvedor líder).
O que é um pouco desconcertante sobre o amadurecido ecossistema Julia é a sua composibilidade. Essencialmente, quando alguém cria uma função de biblioteca genérica como a de DifferentialEquations.jl, você pode usar qualquer tipo AbstractArray / Number para gerar um novo código rapidamente. Portanto, por exemplo, existe uma biblioteca para propagação de erros ( Measurements.jl ) e quando você o cola no solucionador de ODE, ele compila automaticamente uma nova versão do solucionador de ODE que realiza a propagação de erros sem amostragem de parâmetros . Por esse motivo, talvez você não encontre alguns recursos documentados porque o código para os recursos se gera e, portanto, é necessário pensar mais sobre a composição da biblioteca.
Uma das maneiras pelas quais a composição é mais útil é na álgebra linear. Os solucionadores de ODE, por exemplo, permitem que você especifique jac_prototype
, permitindo que você especifique o tipo de jacobiano que será usado internamente. Claro que há coisas na biblioteca padrão LineraAlgebra como Symmetric
e Tridiagonal
você pode usar aqui, mas dada a utilidade de composibility no tipo de algoritmos genéricos, as pessoas têm até agora ido e construiu bibliotecas de tipo matriz inteira. BandedMatrices.jl e BlockBandedMatrices.jl são bibliotecas que definem tipos de matriz em faixas (Block) que possuem lu
sobrecargas rápidas , tornando-os uma boa maneira de acelerar a solução de discretizações MOL rígidas de sistemas de equações diferenciais parciais. PDMats.jlpermite a especificação de matrizes positivas-definidas. Elemental.jl permite definir um jacobiano esparso distribuído. CuArrays.jl define matrizes na GPU. Etc.
Então você tem todos os seus tipos de números. O Unitful.jl verifica a unidade no momento da compilação, portanto é uma biblioteca de unidades sem sobrecarga. O DoubleFloats.jl é uma biblioteca rápida e de alta precisão, juntamente com o Quadmath.jl e o ArbFloats.jl . O ForwardDiff.jl é uma biblioteca para diferenciação automática no modo de avanço que usa aritmética de número duplo. E eu posso continuar listando isso. E sim, você pode jogá-los em bibliotecas Julia suficientemente genéricas como DifferentialEquations.jl para compilar uma versão especificamente otimizada para esses tipos de números. Mesmo algo como ApproxFun.jlque funciona como objetos algébricos (como Chebfun) trabalha com esse sistema genérico, permitindo a especificação de PDEs como ODEs em escalares em um espaço de funções.
Dadas as vantagens da composibilidade e a maneira como os tipos podem ser usados para gerar código novo e eficiente nas funções genéricas de Julia, tem havido muito trabalho para obter implementações da funcionalidade básica da computação científica na Julia pura. Optim.jl para otimização não linear, NLsolve.jl para resolver sistemas não lineares, IterativeSolvers.jl para solucionadores iterativos de sistemas lineares e sistemas eigensistemas, BlackBoxOptim.jl para otimização de caixa preta, etc. Até a biblioteca de rede neural Flux.jl apenas usa CuArrays. Compilação automática de código de jl na GPU por seus recursos de GPU. Essa composibilidade foi o núcleo do que criou coisas como equações diferenciais neurais no DiffEqFlux.jl. As linguagens de programação probabilística, como o Turing.jl, também estão bastante maduras agora e fazem uso das mesmas ferramentas subjacentes.
Como as bibliotecas de Julia são tão fundamentalmente baseadas em ferramentas de geração de código, não deve ser surpresa que haja muitas ferramentas em torno da geração de código. O sistema de transmissão de Julia gera kernels fundidos em tempo real que são sobrecarregados por tipos de matriz para fornecer muitos dos recursos mencionados acima. O CUDAnative.jl permite compilar o código Julia nos kernels da GPU. O ModelingToolkit.jl desassocia automaticamente os ASTs em um sistema simbólico para transformar código matemático. Cassette.jlpermite "overdub" a função existente de outra pessoa, usando regras para alterar sua função antes do tempo de compilação (por exemplo: altere todas as suas alocações de matriz para alocações estáticas de matriz e mova operações para a GPU). Trata-se de ferramentas mais avançadas (não espero que todo mundo que faz computação científica assuma o controle direto do compilador), mas é assim que muitas ferramentas da próxima geração estão sendo construídas (ou melhor, como os recursos estão sendo escritos por eles mesmos).
Quanto ao paralelismo, mencionei GPUs, e Julia integrou multithreading e computação distribuída . O multithreading de Julia usará muito em breve uma arquitetura PARTR (runtime de tarefas paralelas) que permite o agendamento automatizado de multithreading aninhado . Se você quiser usar MPI, você pode apenas usar MPI.jl . E, claro, a maneira mais fácil de fazer uso de tudo isso é usar apenas uma configuração do tipo AbstractArray para usar o paralelismo em suas operações.
Julia também possui o ecossistema básico subjacente que você esperaria de uma linguagem de uso geral usada para aplicações científicas. Possui o Juno IDE com um depurador embutido com pontos de interrupção , e possui o Plots.jl para fazer todo tipo de plotagem . Muitas ferramentas específicas também são boas, como Revise.jl atualiza automaticamente suas funções / biblioteca quando um arquivo é salvo . Você possui o DataFrames.jl , as bibliotecas de estatísticas etc. Uma das bibliotecas mais agradáveis é a Distributions.jl, que permite escrever algoritmos genéricos para a distribuição (por exemplo:rand(dist)
pega um número aleatório de qualquer distribuição que foi passada) e há uma carga inteira de distribuições univariadas e multivariadas (e, é claro, o envio acontece em tempo de compilação, tornando tudo tão rápido quanto codificar uma função específica da distribuição). Existe um monte de ferramentas de manipulação de dados , servidores da web etc. Neste ponto, está maduro o suficiente para que, se houver uma coisa científica básica e você espere que ela exista, basta pesquisar no Google com .jl ou Julia e ela aparecerá.
Depois, há algumas coisas a ter em mente no horizonte. O PackageCompiler procura criar binários a partir das bibliotecas Julia, e ele já tem alguns sucessos, mas precisa de mais desenvolvimento. O Makie.jl é uma biblioteca inteira para plotagem acelerada por GPU com interatividade, e ainda precisa de mais trabalho, mas está realmente procurando se tornar a principal biblioteca de plotagem em Julia. O Zygote.jl é uma biblioteca de diferenciação automática de fonte a fonte que não apresenta os problemas de desempenho de um AD baseado em rastreamento (Tracker do Flux, PyTorch, Jax) e que procura trabalhar em todos os códigos Julia puros. Etc.
Em conclusão, você pode encontrar muito movimento em muitos lugares, mas na maioria das áreas já existe uma biblioteca sólida e madura. Não está mais em um lugar em que você pergunta "será adotado?": Julia foi adotada por pessoas o suficiente (milhões de downloads) que tem o momento de permanecer por perto para sempre. Ele tem uma comunidade muito boa, então se você quiser apenas falar sobre computação paralela ou equações diferenciais numéricas, algumas das melhores salas de bate-papo estão no Julialang Slack . Se é um idioma que você deve aprender é uma pergunta pessoal e se é o idioma certo para o seu projeto é uma questão técnica, e essas são diferentes. Mas é uma linguagem que amadureceu e tem o apoio de um grande grupo consistente de desenvolvedores? Isso parece ser afirmativo.