How to accelerate calculations using CUDA-compatible GPUs
You will need Peacock v0.1.2 or later for this feature.
Summary
Pass GPU=true
when creating your Solver
.
solver = Solver(geometry, fourier_space_cutoff, GPU=true)
Full example
By default, Peacock.jl
uses the CPU. However, you may be able to accelerate your calculations if you have a CUDA-compatible GPU.
Let's begin by defining a simple photonic crystal.
using Peacock, PyPlot
function epf(x,y)
# equation of a circle with radius 0.2a
if x^2+y^2 <= 0.2^2
# dielectric inside the circle
return 8.9
else
# air outside the circle
return 1
end
end
# Permeability is unity everywhere
function muf(x,y)
return 1
end
a1 = [1, 0] # first lattice vector
a2 = [0, 1] # second lattice vector
d1 = 0.01 # resolution along first lattice vector
d2 = 0.01 # resolution along second lattice vector
geometry = Geometry(epf, muf, a1, a2, d1, d2)
When we construct the Solver
from the Geometry
, we can pass the GPU
flag. By default, GPU=false
.
fourier_space_cutoff = 9 # larger = more accurate, slower
solver_CPU = Solver(geometry, fourier_space_cutoff)
solver_GPU = Solver(geometry, fourier_space_cutoff, GPU=true)
The fields of the solver_CPU
are standard Julia arrays, but the fields of the solver_GPU
are CUDA arrays which will utilise the GPU.
typeof(solver_CPU.epc) == Array{Complex{Float64},2}
typeof(solver_GPU.epc) == CUDA.CuArray{Complex{Float64},2}
Now, let's compare the time to solve and plot some bands with and without the GPU.
function plot_example_bands(solver, dk)
G = BrillouinZoneCoordinate( 0, 0, "Γ")
X = BrillouinZoneCoordinate(1/2, 0, "X")
M = BrillouinZoneCoordinate(1/2, 1/2, "M")
ks = [G,X,M,G]
figure(figsize=(4,3))
plot_band_diagram(solver, ks, TE, color="red",
bands=1:4, dk=dk, frequency_scale=1/2pi)
plot_band_diagram(solver, ks, TM, color="blue",
bands=1:4, dk=dk, frequency_scale=1/2pi)
ylim(0,0.8)
end
# call once to make sure functions are compiled
plot_example_bands(solver_CPU, 2)
plot_example_bands(solver_GPU, 2)
# time CPU vs GPU
close("all")
@time plot_example_bands(solver_CPU, 0.1)
@time plot_example_bands(solver_GPU, 0.1)
show()
We find a significant speed up using the GPU - ~13.6 seconds vs ~3.6 seconds.
Further reading
- CUDA.jl: CUDA programming in Julia