Parallel computation to speed up for loops

I am computing the Lyapunov exponents in 2D for the system below, by doing a for loop over two parameters (ωA, A) and it takes a really long time.

using Parameters, ChaosTools, DifferentialEquations, Distributed, SharedArrays
function System!(du, u, p, t = 0)
       @unpack ω, ω_A, A = p
        x, y = u
	s = x^2 + y^2
	du[1] = x + ω * y - s * x - A * sin(ω_A * t)
	du[2] = -ω * x + y - s * y
	du
end

@with_kw mutable struct Params
        ω::Real = 2pi
        ω_A::Real = 2pi
        A :: Real = 10
end

I am using the Distributed and SharedArrays packages for parallel computation. However, I am not sure if it is running in parallel since computing one exponent takes only a couple of minutes. How can I speed up the code below?

tmax = 10000
t_trans = 1000
ω_As = par.ω .* range(0.01, 5, 100)
As = range(0.01, 15, 100)
par = Params()

Λ = SharedArray{Float64, 2}(length(As), length(ω_As))
@sync @distributed for i in eachindex(As)
    par.A = As[i]
    for j  in eachindex(ω_As)
        ω_A = ω_As[j]
        par.ω_A = ω_A
        ds = CoupledODEs(System!, [0., 1.], par)
        λs = lyapunovspectrum(ds, tmax; Ttr = t_trans, Δt = 1)
        λs_nonzero = filter(x -> abs.(x) > 1e-8, λs)
        Λ[i,j] = maximum(λs_nonzero)
    end
end
1 Like

A nice performance boost should result from changing this struct to:

@with_kw mutable struct Params
        ω::Float64 = 2pi
        ω_A::Float64 = 2pi
        A :: Float64= 10
end

If you don’t add any workers (either via addprocs or the commandline argument) then it won’t be parallel.

2 Likes

I believe it will be even more efficient if you make it immutable. It doesn’t look like there should be any problems with making them immutable, and in fact it should be much safer in a parallelized environment.

First of all, put the code in a function(!) Secondly, read the performance tips section of the manual: Performance Tips · The Julia Language

Make a fast single-threaded code. After that you can look into parallelization.

Are you running this on multiple nodes? If not, why not use multithreading instead of multiprocessing?

2 Likes

Thank you! It’s much faster now!