@@ -67,36 +67,26 @@ function FESpaces.gather_free_and_dirichlet_values(f::DistributedFESpace,cell_va
6767 return free_values, dirichlet_values
6868end
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
9084end
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
109100end
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
128117end
129118
130119function fetch_vector_ghost_values_cache (vector_partition,partition)
@@ -139,128 +128,92 @@ end
139128function 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)
261213end
262214
263215# FEFunction related
216+
264217"""
265218"""
266219struct DistributedFEFunctionData{T<: AbstractVector } <: GridapType
0 commit comments