Skip to content

Instantly share code, notes, and snippets.

@terasakisatoshi
Last active January 4, 2025 08:23
Show Gist options
  • Save terasakisatoshi/66efe858c1196d0378dde3e8d214bbe7 to your computer and use it in GitHub Desktop.
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
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