Skip to content

Instantly share code, notes, and snippets.

@terasakisatoshi
Last active January 4, 2025 08:23
Show Gist options
  • Select an option

  • Save terasakisatoshi/66efe858c1196d0378dde3e8d214bbe7 to your computer and use it in GitHub Desktop.

Select an option

Save terasakisatoshi/66efe858c1196d0378dde3e8d214bbe7 to your computer and use it in GitHub Desktop.
distributed_compute_mandelbrot.jl
using Distributed
if nworkers() == 1
@info "Start machines..."
p = addprocs(
[
("username@hostname1", 1),
("username@hostname2", 1),
("username@hostname3", 1),
],
dir = "/home/username", # path/to/working/directory/for/workers
exename = "/home/username/.juliaup/bin/julia", # path/to/julia
exeflags="--threads=auto",
)
@info "Machines launched!"
end
@everywhere begin
using DistributedArrays, OffsetArrays
Base.@kwdef struct Param{I,F}
xmin::F = -1.75
xmax::F = 0.75
width::I = 4096
#width::I = 256
ymin::F = -1.25
ymax::F = 1.25
height::I = 4096
#height::I = 256
max_iter::I = 500
end
function mandelbrot_kernel(param::Param, c)
(; max_iter) = param
z = c
for i = 0:max_iter-1
z = z * z + c
abs(z) > 2 && return i
end
max_iter
end
end # everywhere
function makeaxes(param::Param)
(; xmin, xmax, width, ymin, ymax, height) = param
x = range(xmin, xmax, width + 1)[begin:end-1]
y = range(ymin, ymax, height + 1)[begin:end-1]
x, y
end
function makeinput(param::Param)
x, y = makeaxes(param)
complex.(x, y')
end
function distributed_compute_mandelbrot(param::Param, input)
Data = distribute(input)
Result = DArray(size(Data)) do inds # local indices on each processor
arr = zeros(inds) # We create an OffsetArray with the correct local indices
data_local = OffsetArray(localpart(Data), localindices(Data)) # get the local part of data on each processor and assign the proper indices
Base.Threads.@threads for i in eachindex(data_local)
c = data_local[i]
arr[i] = mandelbrot_kernel(param, c)
end
parent(arr) # strip the OffsetArray wrapper
end
return Result
end
using ImageCore
using Sixel
@info "Setup done"
function main()
param = Param()
inputz = makeinput(param)
@time doutput = distributed_compute_mandelbrot(param, inputz)
@time output = Matrix(doutput) # gather data in each processor and collect to host machie
@assert maximum(output) > 0
normalized = output / maximum(output)
gray = colorview(Gray, normalized')
sixel_encode(gray)
end
@info "Run main() manually"
if abspath(PROGRAM_FILE) == @__FILE__
main()
end
@terasakisatoshi
Copy link
Copy Markdown
Author

terasakisatoshi commented Jan 3, 2025

Description

This code calculates the Mandelbrot set using DistributedArrays.jl with multiple nodes (multiple machines).
The base code is based on https://github.com/genkuroki/public/blob/main/0042/mandelbrot%20Julia%201.8.5.ipynb

Result

The following result is derived using 4 x Raspberry Pi 5 = 16 processes.

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment