-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #21 from FHell/multithreading
Multithreading
- Loading branch information
Showing
16 changed files
with
256 additions
and
67 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,3 +7,4 @@ Manifest.toml | |
scratch.jl | ||
docs/build | ||
bugs | ||
design_experiments |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
name = "NetworkDynamics" | ||
uuid = "22e9dc34-2a0d-11e9-0de0-8588d035468b" | ||
authors = ["Frank Hellmann <[email protected]>, Alexander Penner <[email protected]>"] | ||
version = "0.2.0" | ||
authors = ["Frank Hellmann <[email protected]>, Michael Lindner <[email protected]>, Alexander Penner <[email protected]>"] | ||
version = "0.3.0" | ||
|
||
[deps] | ||
DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e" | ||
|
@@ -12,8 +12,8 @@ Reexport = "189a3867-3050-52da-a836-e630ba90ab69" | |
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" | ||
|
||
[compat] | ||
julia = "1" | ||
DiffEqBase = "^6.9.4" | ||
LightGraphs = "^1.3.0" | ||
NLsolve = "^4.2.0" | ||
Reexport = "^0.2.0" | ||
julia = "1" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,11 @@ | ||
name = "NetworkDynamics-Benchmarking" | ||
author = ["Frank Hellmann <[email protected]>"] | ||
authors = ["Frank Hellmann <[email protected]>", | ||
"Michael Lindner <[email protected]>"] | ||
|
||
[deps] | ||
BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf" | ||
Debugger = "31a5f54b-26ea-5ae9-a837-f05ce5417438" | ||
DifferentialEquations = "0c46a032-eb83-5123-abaf-570d42b7fbaa" | ||
LightGraphs = "093fc24a-ae57-5d10-9952-331d41423f4d" | ||
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" | ||
NLsolve = "2774e3e8-f4cf-5e23-947b-6d7e65073b56" | ||
|
@@ -14,5 +16,6 @@ Profile = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79" | |
ProfileView = "c46f51b8-102a-5cf2-8d2c-8597cb0e0da7" | ||
PyPlot = "d330b81b-6aea-500a-939a-2ce795aea3ee" | ||
Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" | ||
SimpleWeightedGraphs = "47aef6b3-ad0c-573a-a1e2-d07658019622" | ||
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" | ||
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
# call from shell: env JULIA_NUM_THREADS=1 julia mutltithreading_benchmarks.jl | ||
|
||
using NetworkDynamics | ||
using LightGraphs | ||
using BenchmarkTools | ||
|
||
### Defining a graph | ||
|
||
N = 100 # number of nodes | ||
k = 20 # average degree | ||
g = barabasi_albert(N, k) # a little more exciting than a bare random graph | ||
|
||
|
||
### Functions for edges and vertices | ||
|
||
@inline Base.@propagate_inbounds function diffusionedge!(e, v_s, v_d, p, t) | ||
# usually e, v_s, v_d are arrays, hence we use the broadcasting operator . | ||
e .= p * (v_s .- v_d) | ||
nothing | ||
end | ||
|
||
@inline Base.@propagate_inbounds function diffusionvertex!(dv, v, e_s, e_d, p, t) | ||
# usually v, e_s, e_d are arrays, hence we use the broadcasting operator . | ||
dv .= p | ||
# edges for which v is the source | ||
for e in e_s | ||
dv .-= e | ||
end | ||
# edges for which v is the destination | ||
for e in e_d | ||
dv .+= e | ||
end | ||
nothing | ||
end | ||
|
||
### Constructing the network dynamics | ||
|
||
nd_diffusion_vertex = ODEVertex(f! = diffusionvertex!, dim = 1) | ||
nd_diffusion_edge = StaticEdge(f! = diffusionedge!, dim = 1) | ||
|
||
|
||
### Benchmarking | ||
println("Number of Threads: ", haskey(ENV, "JULIA_NUM_THREADS") ? ENV["JULIA_NUM_THREADS"] : "1") | ||
println("\nBenchmarking ODE_Static...") | ||
p = (collect(1:nv(g))./nv(g) .- 0.5, .5 .* ones(ne(g))) | ||
println("\nsingle-threaded...") | ||
nd = network_dynamics(nd_diffusion_vertex, nd_diffusion_edge, g, parallel=false) | ||
display(@benchmark nd(randn(N), randn(N), p , 0,)) | ||
println("\nparallel...") | ||
nd = network_dynamics(nd_diffusion_vertex, nd_diffusion_edge, g, parallel=true) | ||
display(@benchmark nd(randn(N), randn(N), p , 0,)) | ||
#= | ||
### Simulation | ||
using OrdinaryDiffEq | ||
x0 = randn(N) | ||
ode_prob = ODEProblem(nd, x0, (0., 4.), p) | ||
sol = solve(ode_prob, Tsit5()); | ||
### Plotting | ||
using Plots | ||
plot(sol, vars = syms_containing(nd, "v")) | ||
=# | ||
### Redefinition | ||
|
||
@inline Base.@propagate_inbounds function diffusion_dedge!(de, e, v_s, v_d, p, t) | ||
de .= 100. * (p * sin.(v_s - v_d) - e) | ||
nothing | ||
end | ||
|
||
nd_diffusion_dedge = ODEEdge(f! = diffusion_dedge!, dim = 1) | ||
|
||
|
||
|
||
p = (collect(1:nv(g))./nv(g) .- 0.5, 5 .* ones(ne(g))) | ||
|
||
### Benchmarking | ||
println("\nBenchmarking ODE_ODE...") | ||
println("\nsingle-threaded...") | ||
nd_ode = network_dynamics(nd_diffusion_vertex, nd_diffusion_dedge, g, parallel=false) | ||
display(@benchmark nd_ode(randn(nv(g) + ne(g)), randn(nv(g) + ne(g)), p , 0,)) | ||
println("\nparallel...") | ||
nd_ode = network_dynamics(nd_diffusion_vertex, nd_diffusion_dedge, g, parallel=true) | ||
display(@benchmark nd_ode(randn(nv(g) + ne(g)), randn(nv(g) + ne(g)), p , 0,)) | ||
|
||
|
||
println("") | ||
#= | ||
### Simulation | ||
x0 = randn(nv(g) + ne(g)) | ||
ode_ode_prob = ODEProblem(nd_ode, x0, (0., 2.), p) | ||
sol_ode = solve(ode_ode_prob, Tsit5()); | ||
### Plotting | ||
plot(sol_ode, vars = syms_containing(nd, "v")) | ||
=# |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Multi-Threading | ||
|
||
Since version `0.3.0` multi-threading via the `Threads.@threads` macro is possible. This allows julia to integrate different nodes and edges in different threads, and leads to significant performance gains on parallel architectures. To enable multi-threading call `network_dynamics` with the keyword argument `parallel=true`. | ||
|
||
```julia | ||
network_dynamics(vertices!, edges!, graph, parallel=true) | ||
``` | ||
|
||
In order for this to take effect, multiple threads have to be available. This is achieved by setting the environment variable `JULIA_NUM_THREADS` **before** starting Julia. To start Julia from a bash shell and with 4 threads use: | ||
``` | ||
$ env JULIA_NUM_THREADS=4 julia | ||
``` | ||
|
||
If you are using `Juno` for the `Atom` text editor `JULIA_NUM_THREADS` is set to the number of physical cores of your processor by default. This is also the number of threads we recommend to use. | ||
|
||
!!! note | ||
The thread handling causes a small overhead in the order of *20 μs* per call to the ODE function which might impair performance on small networks (5 to 20 nodes) or on single core machines. In theses cases `network_dynamics` can be called without any additional arguments, since `parallel` defaults to `false`. | ||
|
||
|
||
|
||
For more information on setting environment varibales see the [Julia documentation](https://docs.julialang.org/en/v1/manual/environment-variables/index.html#JULIA_NUM_THREADS-1). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.