Skip to content

Commit

Permalink
WIP MPI models (don't run me plz I'm broken)
Browse files Browse the repository at this point in the history
  • Loading branch information
utkinis committed Nov 13, 2023
1 parent aac257a commit 4f263d7
Show file tree
Hide file tree
Showing 6 changed files with 162 additions and 126 deletions.
233 changes: 127 additions & 106 deletions scripts_future_API/tm_stokes_mpi_wip.jl
Original file line number Diff line number Diff line change
@@ -1,129 +1,150 @@
using FastIce
using FastIce.Architectures
using FastIce.Grids
using FastIce.Fields
using FastIce.Utils
using FastIce.BoundaryConditions
using FastIce.Models.FullStokes.Isothermal
using FastIce.Physics
using FastIce.Distributed
using FastIce.KernelLaunch

using MPI
const VBC = BoundaryCondition{Velocity}
const TBC = BoundaryCondition{Traction}
const SBC = BoundaryCondition{Slip}

using KernelAbstractions

using Printf

MPI.Init()

dims = (0, 0, 0)
# using GLMakie

topology = CartesianTopology(dims)

me = global_rank(topology)
device_id = shared_rank(topology)
comm = cartesian_communicator(topology)
dims = dimensions(topology)
using FastIce.Distributed
using MPI

size_l = (64, 64, 64)
MPI.Init()

size_g = global_grid_size(topology, size_l)
backend = CPU()
dims = (2, 0, 2)
arch = Architecture(backend, dims, MPI.COMM_WORLD)

# physics
ebg = 1.0

global_grid = CartesianGrid(
origin = (-0.5, -0.5, 0.0),
extent = ( 1.0, 1.0, 1.0),
size = size_g,
)

grid = local_grid(global_grid, topology)

@printf("process %d/%d on node %s, global rank %02d\n", device_id + 1, node_size(topology), node_name(topology), me + 1)

# psh_x(x, _, _) = -x*ebg
# psh_y(_, y, _) = y*ebg

# x_bc = BoundaryFunction(psh_x; reduce_dims=false)
# y_bc = BoundaryFunction(psh_y; reduce_dims=false)

# boundary_conditions = (
# west = BoundaryCondition{Velocity}(x_bc, y_bc, 0.0),
# east = BoundaryCondition{Velocity}(x_bc, y_bc, 0.0),
# south = BoundaryCondition{Velocity}(x_bc, y_bc, 0.0),
# north = BoundaryCondition{Velocity}(x_bc, y_bc, 0.0),
# bottom = BoundaryCondition{Velocity}(0.0 , 0.0 , 0.0),
# top = BoundaryCondition{Velocity}(0.0 , 0.0 , 0.0),
# )

# r = 0.7
# re_mech = 10π
# lτ_re_m = minimum(extent(grid)) / re_mech
# vdτ = minimum(spacing(grid)) / sqrt(10.1)
# θ_dτ = lτ_re_m * (r + 4 / 3) / vdτ
# dτ_r = 1.0 / (θ_dτ + 1.0)
# nudτ = vdτ * lτ_re_m

# iter_params = (
# η_rel = 1e-1,
# Δτ = ( Pr = r / θ_dτ, τ = (xx = dτ_r, yy = dτ_r, zz = dτ_r, xy = dτ_r, xz = dτ_r, yz = dτ_r), V = (x = nudτ, y = nudτ, z = nudτ)),
# )

# backend = CPU()

# physics = (rheology = GlensLawRheology(1), )
# other_fields = (
# A = Field(backend, grid, Center()),
# )

# init_incl(x, y, z, x0, y0, z0, r, Ai, Am) = ifelse((x-x0)^2 + (y-y0)^2 + (z-z0)^2 < r^2, Ai, Am)
# set!(other_fields.A, grid, init_incl; parameters = (x0 = 0.0, y0 = 0.0, z0 = 0.5, r = 0.2, Ai = 1e1, Am = 1.0))

# model = IsothermalFullStokesModel(;
# backend,
# grid,
# physics,
# boundary_conditions,
# iter_params,
# other_fields
# )

# fig = Figure(resolution=(1000,1000), fontsize=32)
# axs = (
# Pr = Axis(fig[1,1][1,1]; aspect=DataAspect(), xlabel="x", ylabel="y", title="Pr"),
# Vx = Axis(fig[2,1][1,1]; aspect=DataAspect(), xlabel="x", ylabel="y", title="Vx"),
# Vy = Axis(fig[2,2][1,1]; aspect=DataAspect(), xlabel="x", ylabel="y", title="Vy"),
# )

# plt = (
# Pr = heatmap!(axs.Pr, xcenters(grid), ycenters(grid), interior(model.fields.Pr)[:, :, size(grid,3)÷2]; colormap=:turbo),
# Vx = heatmap!(axs.Vx, xvertices(grid), ycenters(grid), interior(model.fields.V.x)[:, :, size(grid,3)÷2]; colormap=:turbo),
# Vy = heatmap!(axs.Vy, xcenters(grid), yvertices(grid), interior(model.fields.V.y)[:, :, size(grid,3)÷2]; colormap=:turbo),
# )
# Colorbar(fig[1,1][1,2], plt.Pr)
# Colorbar(fig[2,1][1,2], plt.Vx)
# Colorbar(fig[2,2][1,2], plt.Vy)
topo = details(arch)

size_l = (32, 32, 32)
size_g = global_grid_size(topo, size_l)

if global_rank(topo) == 0
@show dimensions(topo)
@show size_g
end

grid_g = CartesianGrid(; origin=(-1.0, -0.5, 0.0),
extent=(2.0, 1.0, 2.0),
size=size_g)

grid_l = local_grid(grid_g, topo)

psh_x(x, _, _) = -x * ebg
psh_y(_, y, _) = y * ebg

x_bc = BoundaryFunction(psh_x; reduce_dims=false)
y_bc = BoundaryFunction(psh_y; reduce_dims=false)

boundary_conditions = (x = (VBC(x_bc, y_bc, 0.0), VBC(x_bc, y_bc, 0.0)),
y = (VBC(x_bc, y_bc, 0.0), VBC(x_bc, y_bc, 0.0)),
z = (SBC(0.0, 0.0, 0.0), TBC(0.0, 0.0, 0.0)))

# numerics
nt = 1000
nviz = 10

r = 0.7
re_mech = 10π
lτ_re_m = minimum(extent(grid_g)) / re_mech
vdτ = minimum(spacing(grid_g)) / sqrt(ndims(grid_g) * 3.1)
θ_dτ = lτ_re_m * (r + 4 / 3) / vdτ
dτ_r = 1.0 / (θ_dτ + 1.0)
nudτ = vdτ * lτ_re_m

iter_params = (η_rel=1e-1,
Δτ=(Pr=r / θ_dτ, τ=(xx=dτ_r, yy=dτ_r, zz=dτ_r, xy=dτ_r, xz=dτ_r, yz=dτ_r), V=(x=nudτ, y=nudτ, z=nudτ)))

physics = (rheology=GlensLawRheology(1),)
other_fields = (A=Field(backend, grid_l, Center()),)

init_incl(x, y, z, x0, y0, z0, r, Ai, Am) = ifelse((x - x0)^2 + (y - y0)^2 + (z - z0)^2 < r^2, Ai, Am)
set!(other_fields.A, grid_l, init_incl; parameters=(x0=0.0, y0=0.0, z0=0.5, r=0.2, Ai=1e-1, Am=1.0))

model = IsothermalFullStokesModel(;
arch,
grid=grid_l,
physics,
boundary_conditions,
iter_params,
other_fields)

# if global_rank(topo) == 0
# fig = Figure(; resolution=(1200, 1000), fontsize=32)
# axs = (Pr=Axis(fig[1, 1][1, 1]; aspect=DataAspect(), xlabel="x", ylabel="z", title="Pr"),
# Vx=Axis(fig[1, 2][1, 1]; aspect=DataAspect(), xlabel="x", ylabel="z", title="Vx"),
# Vy=Axis(fig[2, 1][1, 1]; aspect=DataAspect(), xlabel="x", ylabel="z", title="Vy"),
# Vz=Axis(fig[2, 2][1, 1]; aspect=DataAspect(), xlabel="x", ylabel="z", title="Vz"))

# plt = (Pr=heatmap!(axs.Pr, xcenters(grid_l), zcenters(grid_l), interior(model.fields.Pr)[:, size(grid_l, 2)÷2, :]; colormap=:turbo),
# Vx=heatmap!(axs.Vx, xvertices(grid_l), zcenters(grid_l), interior(model.fields.V.x)[:, size(grid_l, 2)÷2, :]; colormap=:turbo),
# Vy=heatmap!(axs.Vy, xcenters(grid_l), zcenters(grid_l), interior(model.fields.V.y)[:, size(grid_l, 2)÷2, :]; colormap=:turbo),
# Vz=heatmap!(axs.Vz, xcenters(grid_l), zvertices(grid_l), interior(model.fields.V.z)[:, size(grid_l, 2)÷2, :]; colormap=:turbo))
# Colorbar(fig[1, 1][1, 2], plt.Pr)
# Colorbar(fig[1, 2][1, 2], plt.Vx)
# Colorbar(fig[2, 1][1, 2], plt.Vy)
# Colorbar(fig[2, 2][1, 2], plt.Vz)
# end

# set!(model.fields.Pr, 0.0)
# foreach(x -> set!(x, 0.0), model.fields.τ)
# Isothermal._apply_bcs!(model.backend, model.grid, model.fields, model.boundary_conditions.stress)

# set!(model.fields.V.x, grid, psh_x)
# set!(model.fields.V.y, grid, psh_y)
# set!(model.fields.V.z, 0.0)
# Isothermal._apply_bcs!(model.backend, model.grid, model.fields, model.boundary_conditions.velocity)

# set!(model.fields.η, other_fields.A)
# extrapolate!(model.fields.η)

# for it in 1:10
# advance_iteration!(model, 0.0, 1.0; async = false)
# if it % 10 == 0
# plt.Pr[3][] = interior(model.fields.Pr)[:, :, size(grid,3)÷2]
# plt.Vx[3][] = interior(model.fields.V.x)[:, :, size(grid,3)÷2]
# plt.Vy[3][] = interior(model.fields.V.y)[:, :, size(grid,3)÷2]
# yield()
# end

fill!(parent(model.fields.Pr), 0.0)
foreach(x -> fill!(parent(x), 0.0), model.fields.τ)
foreach(x -> fill!(parent(x), 0.0), model.fields.V)

KernelLaunch.apply_all_boundary_conditions!(arch, grid_l, model.boundary_conditions.stress)
println("$(global_rank(topo)) applied stress BCs")

set!(model.fields.V.x, grid_l, psh_x)
set!(model.fields.V.y, grid_l, psh_y)
set!(model.fields.V.z, 0.0)

# println("at rank $(global_rank(topo)) bcs $(typeof(model.boundary_conditions.velocity))")
println("at rank $(global_rank(topo)) topo $topo")
MPI.Barrier(cartesian_communicator(topo))

KernelLaunch.apply_all_boundary_conditions!(arch, grid_l, model.boundary_conditions.velocity)
println("$(global_rank(topo)) applied velocity BCs")

set!(model.fields.η, other_fields.A)
extrapolate!(model.fields.η)

# if global_rank(topo) == 0
# display(fig)
# end

MPI.Finalize()
println("Hi from $(global_rank(topo))")
MPI.Barrier(cartesian_communicator(topo))

for it in 1:nt
advance_iteration!(model, 0.0, 1.0; async=false)
if it % nviz == 0# && global_rank(topo) == 0
if global_rank(topo) == 0
println("it = $it/$nt")
end
# plt.Pr[3][] = interior(model.fields.Pr)[:, size(grid_l, 2)÷2, :]
# plt.Vx[3][] = interior(model.fields.V.x)[:, size(grid_l, 2)÷2, :]
# plt.Vy[3][] = interior(model.fields.V.y)[:, size(grid_l, 2)÷2, :]
# plt.Vz[3][] = interior(model.fields.V.z)[:, size(grid_l, 2)÷2, :]
# yield()
end
end

sleep(30)

MPI.Finalize()
2 changes: 1 addition & 1 deletion src/Architectures.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,6 @@ set_device!(::Architecture{Kind,CPU}) where {Kind} = nothing
get_device(::CPU, id::Integer) = nothing

heuristic_groupsize(arch::Architecture, ::Val{N}) where {N} = heuristic_groupsize(arch.device, Val(N))
heuristic_groupsize(::Architecture{Kind,CPU}, N) where {Kind} = 256
heuristic_groupsize(::Architecture{Kind,CPU}, ::Val{N}) where {Kind,N} = 256

end
2 changes: 1 addition & 1 deletion src/Distributed/Distributed.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ struct DistributedMPI end

function Architectures.Architecture(backend::Backend, dims::NTuple{N,Int}, comm::MPI.Comm=MPI.COMM_WORLD) where {N}
topo = CartesianTopology(dims; comm)
device = get_device(backend, shared_rank(topo))
device = get_device(backend, shared_rank(topo)+1)
return Architecture{DistributedMPI,typeof(backend),typeof(device),typeof(topo)}(backend, device, topo)
end

Expand Down
18 changes: 12 additions & 6 deletions src/Distributed/boundary_conditions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ function apply_boundary_conditions!(::Val{S}, ::Val{D},
info.send_request = MPI.Isend(info.send_buffer, comm; dest=nbrank)
end

recv_ready = BitVector(false for _ in eachindex(exchange_infos))
send_ready = BitVector(false for _ in eachindex(exchange_infos))
recv_ready = falses(N)
send_ready = falses(N)

# test send and receive requests, initiating device-to-device copy
# to the receive buffer if the receive is complete
Expand Down Expand Up @@ -92,15 +92,21 @@ function get_send_view(::Val{2}, ::Val{D}, array::AbstractArray, halo_width::Int
return view(array, indices...)
end

const BatchOrNothing = Union{BoundaryConditionsBatch,Nothing}

function override_boundary_conditions(arch::Architecture{DistributedMPI},
batches::NTuple{N, NTuple{2, BoundaryConditionsBatch}}; exchange=false) where {N}
batches::NTuple{N,NTuple{2,BatchOrNothing}}; exchange=false) where {N}
return ntuple(Val(N)) do D
ntuple(Val(2)) do S
batch = batches[D][S]
if neighbor(details(arch), D, S) != MPI.PROC_NULL
exchange ? BoundaryConditionsBatch(batch.fields, ExchangeInfo.(Val(S), Val(D), batch.fields)) : nothing
if !isnothing(batch)
if neighbor(details(arch), D, S) != MPI.PROC_NULL
exchange ? BoundaryConditionsBatch(batch.fields, ExchangeInfo.(Val(S), Val(D), batch.fields)) : nothing
else
batch
end
else
batch
nothing
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion src/KernelLaunch.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ function launch!(arch::Architecture, grid::CartesianGrid, kernel::Pair{K,Args};
worksize = worksize .+ 2 .* expand
end

groupsize = heuristic_groupsize(arch, length(worksize))
groupsize = heuristic_groupsize(arch, Val(length(worksize)))

if isnothing(hide_boundaries)
fun(backend(arch), groupsize, worksize)(args..., offset)
Expand Down
31 changes: 20 additions & 11 deletions src/Models/full_stokes/isothermal/isothermal.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ using FastIce.Fields
using FastIce.BoundaryConditions
using FastIce.Utils
using FastIce.KernelLaunch
using FastIce.Distributed

include("kernels.jl")

Expand All @@ -31,16 +32,18 @@ struct IsothermalFullStokesModel{Arch,Grid,BC,Physics,IterParams,Fields}
end

function make_fields_mechanics(backend, grid)
return (Pr = Field(backend, grid, Center(); halo=1),
τ = (xx=Field(backend, grid, Center(); halo=1),
yy=Field(backend, grid, Center(); halo=1),
zz=Field(backend, grid, Center(); halo=1),
xy=Field(backend, grid, (Vertex(), Vertex(), Center()); halo=0),
xz=Field(backend, grid, (Vertex(), Center(), Vertex()); halo=0),
yz=Field(backend, grid, (Center(), Vertex(), Vertex()); halo=0)),
V = (x=Field(backend, grid, (Vertex(), Center(), Center()); halo=1),
y=Field(backend, grid, (Center(), Vertex(), Center()); halo=1),
z=Field(backend, grid, (Center(), Center(), Vertex()); halo=1)))
return (Pr=Field(backend, grid, Center(); halo=1),
# deviatoric stress
τ=(xx=Field(backend, grid, Center(); halo=1),
yy=Field(backend, grid, Center(); halo=1),
zz=Field(backend, grid, Center(); halo=1),
xy=Field(backend, grid, (Vertex(), Vertex(), Center()); halo=0),
xz=Field(backend, grid, (Vertex(), Center(), Vertex()); halo=0),
yz=Field(backend, grid, (Center(), Vertex(), Vertex()); halo=0)),
# velocity
V=(x=Field(backend, grid, (Vertex(), Center(), Center()); halo=1),
y=Field(backend, grid, (Center(), Vertex(), Center()); halo=1),
z=Field(backend, grid, (Center(), Center(), Vertex()); halo=1)))
end

function IsothermalFullStokesModel(; arch, grid, boundary_conditions, physics=nothing, iter_params, fields=nothing, other_fields=nothing)
Expand All @@ -60,6 +63,12 @@ function IsothermalFullStokesModel(; arch, grid, boundary_conditions, physics=no

boundary_conditions = make_field_boundary_conditions(grid, fields, boundary_conditions)

if arch isa Architecture{Distributed.DistributedMPI}
stress = override_boundary_conditions(arch, boundary_conditions.stress)
velocity = override_boundary_conditions(arch, boundary_conditions.velocity; exchange=true)
boundary_conditions = (; stress, velocity)
end

return IsothermalFullStokesModel(arch, grid, boundary_conditions, physics, iter_params, fields)
end

Expand All @@ -73,7 +82,7 @@ function advance_iteration!(model::IsothermalFullStokesModel, t, Δt; async=true
Δ = NamedTuple{(:x, :y, :z)}(spacing(model.grid))

launch!(model.arch, model.grid, update_σ! => (Pr, τ, V, η, Δτ, Δ);
location=Vertex(), boundary_conditions=model.boundary_conditions.stress)
location=Vertex(), expand=1, boundary_conditions=model.boundary_conditions.stress)

launch!(model.arch, model.grid, update_V! => (V, Pr, τ, η, Δτ, Δ);
location=Vertex(), boundary_conditions=model.boundary_conditions.velocity)
Expand Down

0 comments on commit 4f263d7

Please sign in to comment.