Julia, a questo punto (maggio 2019, Julia v1.1 con v1.2 sta per uscire) è abbastanza matura per il calcolo scientifico. La versione v1.0 indicava la fine della rottura annuale del codice . Con ciò, molte librerie di informatica scientifica hanno avuto il tempo di crescere semplicemente senza interruzioni. Un'ampia panoramica dei pacchetti Julia è disponibile su pkg.julialang.org .
Per il core computing scientifico, la libreria DifferentialEquations.jl per equazioni differenziali (ODE, SDE, DAE, DDE, simulazioni Gillespie, ecc.), Flux.jl per reti neurali e la libreria JuMP per la programmazione matematica (ottimizzazione: lineare, quadratica, programmazione mista mista, ecc.) sono tre dei cardini dell'ecosistema del calcolo scientifico. La libreria di equazioni differenziali in particolare è molto più sviluppata di quella che vedresti in altre lingue, con un grande team di sviluppo che implementa funzionalità come integratori EPIRK , Runge-Kutta-Nystrom , equazione differenziale ritardo rigido / differenziale-algebrico etempo adattativo equazione rigida differenziale stocastica integratori, insieme ad un sacco di altre cose, come analisi di sensitività adjoint , DSL reazioni chimiche , privo di matrice Newton-Krylov e completo (dati svincolato) compatibilità GPU, con formazione di equazioni differenziali neurali , tutti con risultati di benchmark fantastici (disclaimer: sono lo sviluppatore principale).
La cosa che sbalordisce un po 'l'ecosistema Julia maturato è la sua compostabilità. In sostanza, quando qualcuno crea una funzione di libreria generica come quelle in DifferentialEquations.jl, è possibile utilizzare qualsiasi tipo AbstractArray / Number per generare al volo nuovo codice. Quindi, ad esempio, esiste una libreria per la propagazione degli errori ( Measurements.jl ) e quando lo si inserisce nel solutore ODE, compila automaticamente una nuova versione del solutore ODE che esegue la propagazione degli errori senza campionamento dei parametri . Per questo motivo, potresti non trovare alcune funzionalità documentate perché il codice delle funzionalità si genera da solo, quindi devi pensare di più alla composizione della libreria.
Uno dei modi in cui la composizione è più utile è l'algebra lineare. I risolutori ODE, ad esempio, ti consentono di specificare jac_prototype
, permettendoti di dargli il tipo per il giacobino che verrà usato internamente. Naturalmente ci sono cose nella libreria standard di LineraAlgebra come Symmetric
e Tridiagonal
si può usare qui, ma data l'utilità della composibilità negli algoritmi di tipo generico, le persone sono ormai andate a costruire intere librerie di tipi di array. BandedMatrices.jl e BlockBandedMatrices.jl sono librerie che definiscono tipi di matrice a bande (Block) con lu
sovraccarichi rapidi , rendendoli un modo piacevole per accelerare la soluzione di discretizzazioni MOL rigide di sistemi di equazioni differenziali parziali. PDMats.jlconsente la specifica di matrici definite positive. Elemental.jl ti consente di definire un giacobino sparso distribuito. CuArrays.jl definisce gli array sulla GPU. Eccetera.
Quindi hai tutti i tuoi tipi di numero. Unitful.jl esegue il controllo dell'unità al momento della compilazione, quindi è una libreria di unità senza sovraccarico. DoubleFloats.jl è una libreria di precisione superiore e veloce, insieme a Quadmath.jl e ArbFloats.jl . ForwardDiff.jl è una libreria per la differenziazione automatica in modalità forward che utilizza l'aritmetica a doppio numero. E posso continuare ad elencarli. E sì, puoi gettarli in librerie Julia sufficientemente generiche come DifferentialEquations.jl per compilare una versione specificamente ottimizzata per questi tipi di numeri. Anche qualcosa come ApproxFun.jlche funziona come oggetti algebrici (come Chebfun) funziona con questo sistema generico, consentendo la specifica di PDE come ODE su scalari in uno spazio funzionale.
Dati i vantaggi della compostabilità e il modo in cui i tipi possono essere utilizzati per generare codice nuovo ed efficiente sulle funzioni generiche di Julia, c'è stato molto lavoro per ottenere implementazioni della funzionalità di calcolo scientifico di base in Julia pura. Optim.jl per l'ottimizzazione non lineare, NLsolve.jl per la risoluzione di sistemi non lineari, IterativeSolvers.jl per i solutori iterativi di sistemi lineari e eigensystems, BlackBoxOptim.jl per l'ottimizzazione della scatola nera, ecc. Anche la libreria di rete neurale Flux.jl utilizza solo CuArrays. compilazione automatica di codice jl nella GPU per le sue capacità GPU. Questa compostabilità è stata il nucleo di ciò che ha creato cose come le equazioni differenziali neurali in DiffEqFlux.jl. Anche i linguaggi di programmazione probabilistica come Turing.jl sono abbastanza maturi e fanno uso degli stessi strumenti di base.
Dal momento che le librerie di Julia sono fondamentalmente basate su strumenti di generazione del codice, non dovrebbe sorprendere che ci siano molti strumenti per la generazione del codice. Il sistema di trasmissione di Julia genera al volo kernel fusi che sono sovraccaricati dai tipi di array per fornire molte delle funzionalità sopra menzionate. CUDAnative.jl consente di compilare il codice Julia in kernel GPU. ModelingToolkit.jl elimina automaticamente gli AST in un sistema simbolico per la trasformazione di codice matematico. Cassette.jlconsente di "sovraincidere" la funzione esistente di qualcun altro, utilizzando le regole per modificarne la funzione prima del tempo di compilazione (ad esempio: modificare tutte le allocazioni di array in allocazioni di array statiche e spostare le operazioni nella GPU). Si tratta di strumenti più avanzati (non mi aspetto che tutti coloro che eseguono elaborazioni scientifiche assumano il controllo diretto del compilatore), ma questo è il modo in cui viene costruita la maggior parte degli strumenti di prossima generazione (o meglio, come si scrivono le funzionalità).
Per quanto riguarda il parallelismo, ho menzionato le GPU e Julia ha integrato il multithreading e il calcolo distribuito . Il multithreading di Julia utilizzerà molto presto un'architettura PARTR (parallel-task runtime) che consente la pianificazione automatizzata del multithreading nidificato . Se si desidera utilizzare MPI, si può semplicemente utilizzare MPI.jl . E poi, ovviamente, il modo più semplice per sfruttarlo è semplicemente usare una configurazione di tipo AbstractArray per usare il parallelismo nelle sue operazioni.
Julia ha anche l'ecosistema di base che ti aspetteresti da un linguaggio generico usato per applicazioni scientifiche. Ha l' IDE Juno con un debugger integrato con punti di interruzione , ha Plots.jl per creare tutti i tipi di grafici. Anche molti strumenti specifici sono utili, come Revise.jl aggiorna automaticamente le tue funzioni / libreria quando un file viene salvato. Hai il tuo DataFrames.jl , librerie statistiche , ecc. Una delle librerie più belle in realtà è Distributions.jl che ti permette di scrivere algoritmi generici per la distribuzione (ad esempio:rand(dist)
prende un numero casuale di qualunque distribuzione sia passata), e c'è un intero carico di distribuzioni univariate e multivariate (e ovviamente l'invio avviene in fase di compilazione, rendendo tutto così veloce come codificare una funzione specifica della distribuzione). C'è un sacco di strumenti di gestione dei dati , server Web , ecc. A questo punto è abbastanza maturo che se c'è una cosa scientifica di base e ti aspetteresti che esista, devi solo cercarla su Google con .jl o Julia e verrà visualizzata.
Quindi ci sono alcune cose da tenere a mente all'orizzonte. PackageCompiler sta cercando di creare binari dalle librerie Julia, e ha già alcuni successi ma ha bisogno di più sviluppo. Makie.jl è un'intera libreria per la stampa accelerata con GPU con interattività, e ha ancora bisogno di un po 'più di lavoro, ma sta davvero cercando di diventare la principale libreria di stampa in Julia. Zygote.jl è una libreria di differenziazione automatica da sorgente a fonte che non presenta i problemi di prestazioni di un annuncio di traccia (Flux's Tracker, PyTorch, Jax) basato su traccia e che sta cercando di funzionare su tutti i codici Julia puri. Eccetera.
In conclusione, puoi trovare molto movimento in molti luoghi, ma nella maggior parte delle aree c'è già una solida libreria maturata. Non è più in un posto in cui si chiede "verrà adottato?": Julia è stata adottata da un numero sufficiente di persone (milioni di download) che ha lo slancio per rimanere per sempre. Ha una comunità davvero bella, quindi se vuoi solo sparare la brezza e parlare di calcolo parallelo o equazioni differenziali numeriche, alcune delle migliori chat room per quello sono nel Julialang Slack . Se è una lingua che dovresti imparare è una domanda personale, e se è la lingua giusta per il tuo progetto è una domanda tecnica, e quelli sono diversi. Ma è un linguaggio che è maturato e ha il sostegno di un ampio gruppo coerente di sviluppatori? Sembra un sì affermativo.