Category Archives: Julia

Recent advancements in differential equation solver software

By: Christopher Rackauckas

Re-posted from: http://www.stochasticlifestyle.com/recent-advancements-in-differential-equation-solver-software/

This was a talk given at the Modelica Jubilee Symposium – Future Directions of System Modeling and Simulation.

Recent Advancements in Differential Equation Solver Software

Since the time of the ancient Fortran methods like dop853 and DASSL were created, many advancements in numerical analysis, computational methods, and hardware have accelerated computing. However, many applications of differential equations still rely on the same older software, possibly to their own detriment. In this talk we will describe the recent advancements being made in differential equation solver software, focusing on the Julia-based DifferentialEquations.jl ecosystem. We will show how high order Rosenbrock and IMEX methods have been proven advantageous over traditional BDF implementations in certain problem domains, and the types of issues that give rise to general performance characteristics between the methods. Extensions of these solver methods to adaptive high order methods for stochastic differential-algebraic and delay differential-algebraic equations will be demonstrated, and the potential use cases of these new solvers will be discussed. Acceleration and generalization of adjoint sensitivity analysis through source-to-source reverse-mode automatic differentiation and GPU-compatibility will be demonstrated on neural differential equations, differential equations which incorporate trainable latent neural networks into their derivative functions to automatically learn dynamics from data.

The post Recent advancements in differential equation solver software appeared first on Stochastic Lifestyle.

Checking bounds checking in Julia

By: Posts | vladium

Re-posted from: https://vladium.com/post/20191016/checking-bounds-checking-in-julia/

Ever since my knapsack benchmark I’ve been curious why Julia was still \(\approx 50\%\) slower than either Java or C++ on what essentially were a couple of nested for-loops over a pair of arrays. I’ve done some exploring and now believe that my first guess was correct: much of the remaining Julia overhead is due to its bounds checking.

Eliding bounds checking unconditionally with @inbounds

My first test was to isolate all opt_value() lines with array access into a begin...end block and annotate it with @inbounds:

    function opt_value(W ::Int64, items ::Array{Item}) ::Int64
    ...
    @inbounds(
      begin
          V[items[1].weight:end] .= items[1].value
          ...
          for j in 2 : n
              V, V_prev = V_prev, V
              itemⱼ = items[j]
              for w in 1 : W
                  V_without_itemⱼ = V_prev[w]
              ...
              end
          end
      end
    )
    ...

Here is the data from the original benchmark with added new timing measurements of the above version, labeled julia.ib:


Calculation time as a function of problem size. **julia.ib** labels data obtained from an @inbounds-annotated Julia implementation.

Figure 1: Calculation time as a function of problem size. julia.ib labels data obtained from an @inbounds-annotated Julia implementation.

Nice! With bounds checks elided Julia performance is now in line with Java and C++: its underperformance has decreased to a maximum of \(\approx 15\%\). And Julia is now even the champion for small problem sizes.

Peeking at differences in generated code via @code_native

Another neat facility of Julia allows me to examine JIT-compiled code very easily and right from my REPL session:

julia> d = Knapsack.make_random_data(5_000, 12345)
(5000, Main.Knapsack.Item[Main.Knapsack.Item(609, 6198), ...

julia> @code_native debuginfo=:none Knapsack.opt_value(d[1],d[2])
    .text
    pushq   %rbp
    movq    %rsp, %rbp
    ...
L1165:
    movl    $2, %edx
    jmp L825
    nopw    (%rax,%rax)

I don’t show the full asm listing because that’s not particularly useful unless you’re a low-level programmer. Comparing it with and without @inbounds does confirm, however, that the former version is shorter: about 200 instructions instead of 320.

It is more instructive to look at the compiled version(s) of a simpler function that simply extracts a single slot from an input array:

function getit(a ::Array{Int64})
    return a[123]
end
julia> @code_native getit(rand(Int64, 1000))
    .text
; ┌ @ work.jl:185 within `getit'
; │┌ @ work.jl:185 within `getindex'
    cmpq    $122, 8(%rdi)
    jbe L18
    movq    (%rdi), %rax
    movq    976(%rax), %rax
; │└
    retq
L18:
    pushq   %rbp
    movq    %rsp, %rbp
; │ @ work.jl:185 within `getit'
; │┌ @ array.jl:728 within `getindex'
    movq    %rsp, %rax
    leaq    -16(%rax), %rsi
    movq    %rsi, %rsp
    movq    $123, -16(%rax)
    movabsq $jl_bounds_error_ints, %rax
    movl    $1, %edx
    callq   *%rax
    nopl    (%rax)
; └└

Note the instructions to check the fixed (and 0-based) index against the array input length (cmpq $122, 8(%rdi)) followed by a conditional jump to native C routine jl_bounds_error_ints() that creates and throws a BoundsError exception object. The following version of getit(), with the only array indexing expression annotated with @inbounds, is much shorter:

function getit(a ::Array{Int64})
    return @inbounds a[123]
end
julia> @code_native getit(rand(Int64, 1000))
    .text
; ┌ @ work.jl:185 within `getit'
; │┌ @ work.jl:185 within `getindex'
    movq    (%rdi), %rax
    movq    976(%rax), %rax
; │└
    retq
    nopl    (%rax,%rax)
; └

Disabling bounds checking from command line

It seems that I can get disable bounds checking summarily using –check-bounds=no option:

>julia --check-bounds=no Knapsack.jl

The documentation is somewhat sparse, but it appears that when this option is used it will completely override all @inbounds annotations in the source code, i.e. either all checks are done in a mandatory fashion (“yes”) or none are (“no”). This could be used for “debug” vs “release” calculation runs. However, since bounds checking affects code as it’s being generated, some more documentation is needed to understand how this option works with “pre-compiled” packages and Julia “system” code. I also would like to understand the functionality and use cases for the @propagate_inbounds macro.

JuliaTeam Available on Amazon Web Services (AWS) Marketplace

Cambridge, MAJuliaTeam from Julia Computing is now available for purchase on Amazon Web Services (AWS) Marketplace.

JuliaTeam is an enterprise solution from Julia Computing that makes it easy and safe for developers, data scientists and IT managers to install and manage public and private packages, adhere to enterprise governance policies, deploy and scale applications, manage licenses and set up continuous integration.

The benefits of JuliaTeam include:

  • Work seamlessly behind your firewall
  • Develop and deploy private packages easily
  • Manage private and public packages effortlessly
  • Enterprise governance and support

Julia co-creator and Julia Computing co-founder and CEO Viral Shah explains, “JuliaTeam helps bring the power of the world’s fastest high-performance open source dynamic computing language to enterprises worldwide. Hundreds of companies deploy Julia in production today for mission-critical tasks, and JuliaTeam makes it possible for them to put Julia to work more efficiently and effectively than ever before.”

More information about JuliaTeam is available here, and JuliaTeam on AWS can be purchased here.

About Julia and Julia Computing

Julia is the fastest high-performance open source computing language for data, analytics, algorithmic trading, machine learning, artificial intelligence, and other scientific and numeric computing applications. Julia solves the two language problem by combining the ease of use of Python and R with the speed of C++. Julia provides parallel computing capabilities out of the box and unlimited scalability with minimal effort. Julia has been downloaded more than 10 million times and is used at more than 1,500 universities. Julia co-creators are the winners of the 2019 James H. Wilkinson Prize for Numerical Software and the 2019 Sidney Fernbach Award. Julia has run at petascale on 650,000 cores with 1.3 million threads to analyze over 56 terabytes of data using Cori, one of the ten largest and most powerful supercomputers in the world.

Julia Computing was founded in 2015 by all the creators of Julia to provide products including JuliaTeam, JuliaSure and JuliaRun to businesses and researchers using Julia.