Skip to content

Commit 185a03f

Browse files
committed
Readability and efficiency changes to generate_gids
1 parent aa71c9c commit 185a03f

1 file changed

Lines changed: 65 additions & 112 deletions

File tree

src/FESpaces.jl

Lines changed: 65 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -67,36 +67,26 @@ function FESpaces.gather_free_and_dirichlet_values(f::DistributedFESpace,cell_va
6767
return free_values, dirichlet_values
6868
end
6969

70-
function dof_wise_to_cell_wise!(cell_wise_vector,dof_wise_vector,cell_to_ldofs,cell_prange)
71-
map(cell_wise_vector,
72-
dof_wise_vector,
73-
cell_to_ldofs,
74-
partition(cell_prange)) do cwv,dwv,cell_to_ldofs,indices
70+
function dof_wise_to_cell_wise!(cell_wise_vector,dof_wise_vector,cell_to_ldofs,cell_ids)
71+
map(cell_wise_vector,dof_wise_vector,cell_to_ldofs,cell_ids) do cwv,dwv,cell_to_ldofs,cell_ids
7572
cache = array_cache(cell_to_ldofs)
76-
ncells = length(cell_to_ldofs)
77-
ptrs = cwv.ptrs
78-
data = cwv.data
79-
cell_own_to_local = own_to_local(indices)
80-
for cell in cell_own_to_local
73+
for cell in cell_ids
8174
ldofs = getindex!(cache,cell_to_ldofs,cell)
82-
p = ptrs[cell]-1
75+
p = cwv.ptrs[cell]-1
8376
for (i,ldof) in enumerate(ldofs)
8477
if ldof > 0
85-
data[i+p] = dwv[ldof]
78+
cwv.data[i+p] = dwv[ldof]
8679
end
8780
end
8881
end
8982
end
83+
return cell_wise_vector
9084
end
9185

92-
function cell_wise_to_dof_wise!(dof_wise_vector,cell_wise_vector,cell_to_ldofs,cell_range)
93-
map(dof_wise_vector,
94-
cell_wise_vector,
95-
cell_to_ldofs,
96-
partition(cell_range)) do dwv,cwv,cell_to_ldofs,indices
86+
function cell_wise_to_dof_wise!(dof_wise_vector,cell_wise_vector,cell_to_ldofs,cell_ids)
87+
map(dof_wise_vector,cell_wise_vector,cell_to_ldofs,cell_ids) do dwv,cwv,cell_to_ldofs,cell_ids
9788
cache = array_cache(cell_to_ldofs)
98-
cell_ghost_to_local = ghost_to_local(indices)
99-
for cell in cell_ghost_to_local
89+
for cell in cell_ids
10090
ldofs = getindex!(cache,cell_to_ldofs,cell)
10191
p = cwv.ptrs[cell]-1
10292
for (i,ldof) in enumerate(ldofs)
@@ -106,25 +96,24 @@ function cell_wise_to_dof_wise!(dof_wise_vector,cell_wise_vector,cell_to_ldofs,c
10696
end
10797
end
10898
end
99+
return dof_wise_vector
109100
end
110101

111-
function dof_wise_to_cell_wise(dof_wise_vector,cell_to_ldofs,cell_prange)
112-
cwv = map(cell_to_ldofs) do cell_to_ldofs
113-
cache = array_cache(cell_to_ldofs)
114-
ncells = length(cell_to_ldofs)
115-
ptrs = Vector{Int32}(undef,ncells+1)
116-
for cell in 1:ncells
117-
ldofs = getindex!(cache,cell_to_ldofs,cell)
118-
ptrs[cell+1] = length(ldofs)
119-
end
120-
PArrays.length_to_ptrs!(ptrs)
121-
ndata = ptrs[end]-1
122-
data = Vector{Int}(undef,ndata)
123-
data .= -1
102+
function allocate_cell_wise_vector(T, cell_to_lids)
103+
map(cell_to_lids) do cell_to_lids
104+
ptrs = Arrays.generate_ptrs(cell_to_lids)
105+
data = zeros(T,ptrs[end]-1)
124106
JaggedArray(data,ptrs)
125107
end
126-
dof_wise_to_cell_wise!(cwv,dof_wise_vector,cell_to_ldofs,cell_prange)
127-
cwv
108+
end
109+
110+
function dof_wise_to_cell_wise(
111+
dof_wise_vector, cell_to_ldofs, cell_ids;
112+
T = eltype(eltype(dof_wise_vector))
113+
)
114+
cwv = allocate_cell_wise_vector(T,cell_to_ldofs)
115+
dof_wise_to_cell_wise!(cwv,dof_wise_vector,cell_to_ldofs,cell_ids)
116+
return cwv
128117
end
129118

130119
function fetch_vector_ghost_values_cache(vector_partition,partition)
@@ -139,128 +128,92 @@ end
139128
function generate_gids(
140129
cell_range::PRange,
141130
cell_to_ldofs::AbstractArray{<:AbstractArray},
142-
nldofs::AbstractArray{<:Integer})
131+
nldofs::AbstractArray{<:Integer}
132+
)
133+
ranks = linear_indices(partition(cell_range))
134+
cell_ldofs_to_data = allocate_cell_wise_vector(Int, cell_to_ldofs)
135+
cache_fetch = fetch_vector_ghost_values_cache(cell_ldofs_to_data,partition(cell_range))
143136

144137
# Find and count number owned dofs
145138
ldof_to_owner, nodofs = map(partition(cell_range),cell_to_ldofs,nldofs) do indices,cell_to_ldofs,nldofs
146139
ldof_to_owner = fill(Int32(0),nldofs)
147140
cache = array_cache(cell_to_ldofs)
148-
lcell_to_owner = local_to_owner(indices)
149-
for cell in 1:length(cell_to_ldofs)
150-
owner = lcell_to_owner[cell]
141+
for (cell, owner) in enumerate(local_to_owner(indices))
151142
ldofs = getindex!(cache,cell_to_ldofs,cell)
152143
for ldof in ldofs
153-
if ldof>0
154-
# TODO this simple approach concentrates dofs
155-
# in the last part and creates imbalances
144+
if ldof > 0
145+
# NOTE: this approach concentrates dofs in the last processor
156146
ldof_to_owner[ldof] = max(owner,ldof_to_owner[ldof])
157147
end
158148
end
159149
end
160-
me = part_id(indices)
161-
nodofs = count(p->p==me,ldof_to_owner)
150+
nodofs = count(isequal(part_id(indices)),ldof_to_owner)
162151
ldof_to_owner, nodofs
163152
end |> tuple_of_arrays
164153

165-
cell_ldofs_to_part = dof_wise_to_cell_wise(ldof_to_owner,
166-
cell_to_ldofs,
167-
cell_range)
168-
169-
# Note1 : this call potentially updates cell_prange with the
170-
# info required to exchange info among nearest neighbours
171-
# so that it can be re-used in the future for other exchanges
172-
173-
# Note2 : we need to call reverse() as the senders and receivers are
174-
# swapped in the AssemblyCache of partition(cell_range)
175-
176-
# Exchange the dof owners
177-
cache_fetch=fetch_vector_ghost_values_cache(cell_ldofs_to_part,partition(cell_range))
178-
fetch_vector_ghost_values!(cell_ldofs_to_part,cache_fetch) |> wait
179-
180-
cell_wise_to_dof_wise!(ldof_to_owner,
181-
cell_ldofs_to_part,
182-
cell_to_ldofs,
183-
cell_range)
184-
185154
# Find the global range of owned dofs
186155
first_gdof = scan(+,nodofs,type=:exclusive,init=one(eltype(nodofs)))
187-
188-
# Distribute gdofs to owned ones
189-
ldof_to_gdof = map(first_gdof,ldof_to_owner,partition(cell_range)) do first_gdof,ldof_to_owner,indices
190-
me = part_id(indices)
156+
157+
# Exchange the dof owners. Cell owner always has correct dof owner.
158+
cell_ldofs_to_owner = dof_wise_to_cell_wise!(
159+
cell_ldofs_to_data,ldof_to_owner,cell_to_ldofs,own_to_local(cell_range)
160+
)
161+
fetch_vector_ghost_values!(cell_ldofs_to_owner,cache_fetch) |> wait
162+
cell_wise_to_dof_wise!(
163+
ldof_to_owner,cell_ldofs_to_owner,cell_to_ldofs,ghost_to_local(cell_range)
164+
)
165+
166+
# Fill owned gids
167+
ldof_to_gdof = map(ranks,first_gdof,ldof_to_owner) do rank,first_gdof,ldof_to_owner
191168
offset = first_gdof-1
192-
ldof_to_gdof = Vector{Int}(undef,length(ldof_to_owner))
169+
ldof_to_gdof = zeros(Int,length(ldof_to_owner))
193170
odof = 0
194171
for (ldof,owner) in enumerate(ldof_to_owner)
195-
if owner == me
172+
if owner == rank
196173
odof += 1
197-
ldof_to_gdof[ldof] = odof
198-
else
199-
ldof_to_gdof[ldof] = 0
200-
end
201-
end
202-
for (ldof,owner) in enumerate(ldof_to_owner)
203-
if owner == me
204-
ldof_to_gdof[ldof] += offset
174+
ldof_to_gdof[ldof] = odof + offset
205175
end
206176
end
207177
ldof_to_gdof
208178
end
209179

210-
# Create cell-wise global dofs
211-
cell_to_gdofs = dof_wise_to_cell_wise(ldof_to_gdof,
212-
cell_to_ldofs,
213-
cell_range)
214-
215-
# Exchange the global dofs
180+
# Exchange gids
181+
cell_to_gdofs = dof_wise_to_cell_wise!(
182+
cell_ldofs_to_data,ldof_to_gdof,cell_to_ldofs,own_to_local(cell_range)
183+
)
216184
fetch_vector_ghost_values!(cell_to_gdofs,cache_fetch) |> wait
217185

218-
# Distribute global dof ids also to ghost
219-
map(cell_to_ldofs,cell_to_gdofs,ldof_to_gdof,ldof_to_owner,partition(cell_range)) do cell_to_ldofs,cell_to_gdofs,ldof_to_gdof,ldof_to_owner,indices
220-
gdof = 0
186+
# Fill ghost gids with exchanged information
187+
map(
188+
cell_to_ldofs,cell_to_gdofs,ldof_to_gdof,ldof_to_owner,partition(cell_range)
189+
) do cell_to_ldofs,cell_to_gdofs,ldof_to_gdof,ldof_to_owner,indices
221190
cache = array_cache(cell_to_ldofs)
222-
cell_ghost_to_local = ghost_to_local(indices)
223-
cell_local_to_owner = local_to_owner(indices)
224-
for cell in cell_ghost_to_local
225-
ldofs = getindex!(cache,cell_to_ldofs,cell)
191+
lcell_to_owner = local_to_owner(indices)
192+
for cell in ghost_to_local(indices)
226193
p = cell_to_gdofs.ptrs[cell]-1
194+
ldofs = getindex!(cache,cell_to_ldofs,cell)
195+
cell_owner = lcell_to_owner[cell]
227196
for (i,ldof) in enumerate(ldofs)
228-
if ldof > 0 && ldof_to_owner[ldof] == cell_local_to_owner[cell]
197+
if (ldof > 0) && isequal(ldof_to_owner[ldof],cell_owner)
229198
ldof_to_gdof[ldof] = cell_to_gdofs.data[i+p]
230199
end
231200
end
232201
end
233202
end
234203

235-
dof_wise_to_cell_wise!(cell_to_gdofs,
236-
ldof_to_gdof,
237-
cell_to_ldofs,
238-
cell_range)
239-
204+
dof_wise_to_cell_wise!(cell_to_gdofs,ldof_to_gdof,cell_to_ldofs,own_to_local(cell_range))
240205
fetch_vector_ghost_values!(cell_to_gdofs,cache_fetch) |> wait
241-
242-
cell_wise_to_dof_wise!(ldof_to_gdof,
243-
cell_to_gdofs,
244-
cell_to_ldofs,
245-
cell_range)
206+
cell_wise_to_dof_wise!(ldof_to_gdof,cell_to_gdofs,cell_to_ldofs,ghost_to_local(cell_range))
246207

247208
# Setup DoFs LocalIndices
248209
ngdofs = reduction(+,nodofs,destination=:all,init=zero(eltype(nodofs)))
249-
local_indices = map(ngdofs,partition(cell_range),ldof_to_gdof,ldof_to_owner) do ngdofs,
250-
indices,
251-
ldof_to_gdof,
252-
ldof_to_owner
253-
me = part_id(indices)
254-
LocalIndices(ngdofs,me,ldof_to_gdof,ldof_to_owner)
255-
end
210+
local_indices = map(LocalIndices,ngdofs,ranks,ldof_to_gdof,ldof_to_owner)
256211

257-
# Setup dof range
258-
dofs_range = PRange(local_indices)
259-
260-
return dofs_range
212+
return PRange(local_indices)
261213
end
262214

263215
# FEFunction related
216+
264217
"""
265218
"""
266219
struct DistributedFEFunctionData{T<:AbstractVector} <: GridapType

0 commit comments

Comments
 (0)