|
| 1 | + |
| 2 | +# This is copied from PArrays v0.5, which is not yet supported. It is necessary to get |
| 3 | +# more than one layers of ghosts. |
| 4 | + |
| 5 | +function _uniform_partition(rank,np,n,args...) |
| 6 | + @assert prod(np) == length(rank) |
| 7 | + indices = map(rank) do rank |
| 8 | + _block_with_constant_size(rank,np,n,args...) |
| 9 | + end |
| 10 | + if length(args) == 0 |
| 11 | + map(indices) do indices |
| 12 | + cache = assembly_cache(indices) |
| 13 | + copy!(cache,empty_assembly_cache()) |
| 14 | + end |
| 15 | + else |
| 16 | + assembly_neighbors(indices;symmetric=true) |
| 17 | + end |
| 18 | + indices |
| 19 | +end |
| 20 | + |
| 21 | +function _block_with_constant_size(rank,np,n,ghost,periodic=map(i->false,ghost)) |
| 22 | + N = length(n) |
| 23 | + p = CartesianIndices(np)[rank] |
| 24 | + own_ranges = map(_local_range,Tuple(p),np,n) |
| 25 | + local_ranges = map(_local_range,Tuple(p),np,n,ghost,periodic) |
| 26 | + owners = map(Tuple(p), np, n, local_ranges) do p, np, n, lr |
| 27 | + myowners = zeros(Int32,length(lr)) |
| 28 | + i = 1 |
| 29 | + for p in Iterators.cycle(1:np) |
| 30 | + plr = _local_range(p, np, n) |
| 31 | + while mod(lr[i]-1, n)+1 in plr |
| 32 | + myowners[i] = p |
| 33 | + (i += 1) > length(myowners) && return myowners |
| 34 | + end |
| 35 | + end |
| 36 | + end |
| 37 | + n_local = prod(map(length, local_ranges)) |
| 38 | + n_own = prod(map(length, own_ranges)) |
| 39 | + n_ghost = n_local - n_own |
| 40 | + |
| 41 | + ghost_to_global = zeros(Int,n_ghost) |
| 42 | + ghost_to_owner = zeros(Int32,n_ghost) |
| 43 | + perm = zeros(Int32,n_local) |
| 44 | + i_ghost = 0 |
| 45 | + i_own = 0 |
| 46 | + |
| 47 | + cis = CartesianIndices(map(length,local_ranges)) |
| 48 | + lis = CircularArray(LinearIndices(n)) |
| 49 | + local_cis = CartesianIndices(local_ranges) |
| 50 | + owner_lis = LinearIndices(np) |
| 51 | + for (i,ci) in enumerate(cis) |
| 52 | + flags = map(Tuple(ci), own_ranges, local_ranges) do i, or, lr |
| 53 | + i in (or .- first(lr) .+ 1) |
| 54 | + end |
| 55 | + if !all(flags) |
| 56 | + i_ghost += 1 |
| 57 | + ghost_to_global[i_ghost] = lis[local_cis[i]] |
| 58 | + o = map(getindex,owners,Tuple(ci)) |
| 59 | + o_ci = CartesianIndex(o) |
| 60 | + ghost_to_owner[i_ghost] = owner_lis[o_ci] |
| 61 | + perm[i] = i_ghost + n_own |
| 62 | + else |
| 63 | + i_own += 1 |
| 64 | + perm[i] = i_own |
| 65 | + end |
| 66 | + end |
| 67 | + ghostids = GhostIndices(prod(n),ghost_to_global,ghost_to_owner) |
| 68 | + ids = PartitionedArrays.LocalIndicesWithConstantBlockSize(p,np,n,ghostids) |
| 69 | + PartitionedArrays.PermutedLocalIndices(ids,perm) |
| 70 | +end |
| 71 | + |
| 72 | +function _local_range(p,np,n,ghost=false,periodic=false) |
| 73 | + l, rem = divrem(n, np) |
| 74 | + offset = l * (p-1) |
| 75 | + if rem >= (np-p+1) |
| 76 | + l += 1 |
| 77 | + offset += p - (np-rem) - 1 |
| 78 | + end |
| 79 | + start = 1+offset-ghost |
| 80 | + stop = l+offset+ghost |
| 81 | + |
| 82 | + periodic && return start:stop |
| 83 | + return max(1, start):min(n,stop) |
| 84 | +end |
0 commit comments