Skip to content

Commit a948ae4

Browse files
authored
Merge pull request #173 from Joroks/nghosts
Allow uniform_partition to have arbitrarily many ghost layers
2 parents 0b6e2b4 + d322a98 commit a948ae4

File tree

2 files changed

+59
-55
lines changed

2 files changed

+59
-55
lines changed

src/p_range.jl

+43-55
Original file line numberDiff line numberDiff line change
@@ -548,12 +548,14 @@ interface.
548548
- `ranks`: Array containing the distribution of ranks.
549549
- `np::NTuple{N}`: Number of parts per direction.
550550
- `n::NTuple{N}`: Number of global indices per direction.
551-
- `ghost::NTuple{N}=ntuple(i->false,N)`: Use or not ghost indices per direction.
551+
- `ghost::NTuple{N}=ntuple(i->false,N)`: Number of ghost indices per direction.
552552
- `periodic::NTuple{N}=ntuple(i->false,N)`: Use or not periodic boundaries per direction.
553553
554554
For convenience, one can also provide scalar inputs instead tuples
555555
to create 1D block partitions. In this case, the argument `np` can be omitted
556-
and it will be computed as `np=length(ranks)`.
556+
and it will be computed as `np=length(ranks)`. At the moment, it's only possible
557+
to use this syntax for zero (with `ghost=false`) or one (with `ghost=true`) layer(s)
558+
of ghost indices. If you wish to have more ghost indices, use tuples instead.
557559
558560
# Examples
559561
@@ -622,42 +624,35 @@ function block_with_constant_size(rank,np,n,ghost,periodic=map(i->false,ghost))
622624
p = CartesianIndices(np)[rank]
623625
own_ranges = map(local_range,Tuple(p),np,n)
624626
local_ranges = map(local_range,Tuple(p),np,n,ghost,periodic)
625-
owners = map(Tuple(p),own_ranges,local_ranges) do p,or,lr
627+
owners = map(Tuple(p), np, n, local_ranges) do p, np, n, lr
626628
myowners = zeros(Int32,length(lr))
627-
for i in 1:length(lr)
628-
if lr[i] in or
629+
i = 1
630+
for p in Iterators.cycle(1:np)
631+
plr = local_range(p, np, n)
632+
while mod(lr[i]-1, n)+1 in plr
629633
myowners[i] = p
634+
(i += 1) > length(myowners) && return myowners
630635
end
631636
end
632-
if myowners[1] == 0
633-
myowners[1] = p-1
634-
end
635-
if myowners[end] == 0
636-
myowners[end] = p+1
637-
end
638-
myowners
639-
end
640-
n_ghost = 0
641-
cis = CartesianIndices(map(length,local_ranges))
642-
predicate(p,i,owners) = owners[i] == p
643-
for ci in cis
644-
flags = map(predicate,Tuple(p),Tuple(ci),owners)
645-
if !all(flags)
646-
n_ghost += 1
647-
end
648637
end
638+
n_local = prod(map(length, local_ranges))
639+
n_own = prod(map(length, own_ranges))
640+
n_ghost = n_local - n_own
641+
649642
ghost_to_global = zeros(Int,n_ghost)
650643
ghost_to_owner = zeros(Int32,n_ghost)
651-
n_local = prod(map(length,local_ranges))
652644
perm = zeros(Int32,n_local)
653645
i_ghost = 0
654646
i_own = 0
655-
n_own = prod(map(length,own_ranges))
647+
648+
cis = CartesianIndices(map(length,local_ranges))
656649
lis = CircularArray(LinearIndices(n))
657650
local_cis = CartesianIndices(local_ranges)
658-
owner_lis = CircularArray(LinearIndices(np))
651+
owner_lis = LinearIndices(np)
659652
for (i,ci) in enumerate(cis)
660-
flags = map(predicate,Tuple(p),Tuple(ci),owners)
653+
flags = map(Tuple(ci), own_ranges, local_ranges) do i, or, lr
654+
i in (or .- first(lr) .+ 1)
655+
end
661656
if !all(flags)
662657
i_ghost += 1
663658
ghost_to_global[i_ghost] = lis[local_cis[i]]
@@ -809,39 +804,32 @@ function renumber_partition(partition_in;renumber_local_indices=true)
809804
end
810805

811806
function local_range(p,np,n,ghost=false,periodic=false)
812-
l = n ÷ np
807+
l, rem = divrem(n, np)
813808
offset = l * (p-1)
814-
rem = n % np
815809
if rem >= (np-p+1)
816-
l = l + 1
817-
offset = offset + p - (np-rem) - 1
818-
end
819-
start = 1+offset
820-
stop = l+offset
821-
if ghost && np != 1
822-
if periodic || p!=1
823-
start -= 1
824-
end
825-
if periodic || p!=np
826-
stop += 1
827-
end
828-
end
829-
start:stop
830-
end
831-
832-
function boundary_owner(p,np,n,ghost=false,periodic=false)
833-
start = p
834-
stop = p
835-
if ghost && np != 1
836-
if periodic || p!=1
837-
start -= 1
838-
end
839-
if periodic || p!=np
840-
stop += 1
841-
end
810+
l += 1
811+
offset += p - (np-rem) - 1
842812
end
843-
(start,p,stop)
844-
end
813+
start = 1+offset-ghost
814+
stop = l+offset+ghost
815+
816+
periodic && return start:stop
817+
return max(1, start):min(n,stop)
818+
end
819+
820+
## unused
821+
# function boundary_owner(p,np,n,ghost=false,periodic=false)
822+
# start = p
823+
# stop = p
824+
825+
# if periodic || p!=1
826+
# start -= ghost
827+
# end
828+
# if periodic || p!=np
829+
# stop += ghost
830+
# end
831+
# (start,p,stop)
832+
# end
845833

846834
struct VectorFromDict{Tk,Tv} <: AbstractVector{Tv}
847835
dict::Dict{Tk,Tv}

test/p_range_tests.jl

+16
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,22 @@ function p_range_tests(distribute)
5151
periodic = (true,true)
5252
uniform_partition(rank,np,n,ghost,periodic)
5353

54+
# uniform Cartesian partition with two layers of ghosts
55+
# in the selected directions
56+
# pzeros fails, if the partition is not consistent
57+
np = (2,2)
58+
n = (10,10)
59+
ghost = (2,2)
60+
uniform_partition(rank,np,n,ghost) |> pzeros
61+
62+
# uniform Cartesian partition with two layers of ghosts
63+
# in the selected directions
64+
# pzeros fails, if the partition is not consistent
65+
np = (2,2)
66+
n = (10,10)
67+
periodic = (true,true)
68+
uniform_partition(rank,np,n,ghost,periodic) |> pzeros
69+
5470
# Custom linear partition with no ghost
5571
n_own = map(rank) do rank
5672
mod(rank,3) + 2

0 commit comments

Comments
 (0)