169 integer,
intent(in) :: send_pe(:), recv_pe(:)
170 type(
stack_i4_t),
intent(inout) :: send_dof(0:), recv_dof(0:)
172 logical,
allocatable :: active(:)
173 integer,
allocatable :: rdest(:), rorig(:), rlen(:)
174 integer,
allocatable :: ndest(:), norig(:), nlen(:)
175 integer,
allocatable :: smeta(:), rmeta(:), rmeta2(:)
176 integer,
allocatable :: kidx(:), sidx(:), pack_dof(:)
177 integer :: lo, hi, m, half, mid, r, partner
178 integer :: s, nst, nstmax, sel, nrec, nnew, off, t
179 integer :: i, j, k, nkw, nsw, nrw, nr2w, nsrec, nrrec, nr2rec
180 integer :: dst, src, src2, curlen
181 logical :: lower, keepit
188 allocate(rdest(
max(nrec, 1)), rorig(
max(nrec, 1)), rlen(
max(nrec, 1)))
191 rdest(i) = send_pe(i)
193 rlen(i) = send_dof(send_pe(i))%size()
194 this%ntotal = this%ntotal + rlen(i)
196 this%nwrk = this%ntotal
206 allocate(st(
max(nstmax, 1)), active(
max(nstmax, 1)))
213 do while (hi - lo .gt. 1)
227 if (r .lt. half)
then
237 if (iand(m, 1) .eq. 1)
then
238 if ((.not. lower) .and. ((
pe_rank - mid) .eq. half))
then
251 keepit = ((rdest(i) .lt. mid) .eqv. lower)
260 allocate(kidx(
max(nkw, 1)), sidx(
max(nsw, 1)))
267 keepit = ((rdest(i) .lt. mid) .eqv. lower)
278 smeta(
cr_rec*nsrec + 1) = rdest(i)
279 smeta(
cr_rec*nsrec + 2) = rorig(i)
280 smeta(
cr_rec*nsrec + 3) = rlen(i)
290 if (src2 .ge. 0)
then
298 nrw = nrw + rmeta(
cr_rec*(i-1) + 3)
302 nr2w = nr2w + rmeta2(
cr_rec*(i-1) + 3)
307 nnew = (nrec - nsrec) + nrrec + nr2rec
308 allocate(ndest(
max(nnew, 1)), norig(
max(nnew, 1)), nlen(
max(nnew, 1)))
311 if ((rdest(i) .lt. mid) .eqv. lower)
then
320 ndest(j) = rmeta(
cr_rec*(i-1) + 1)
321 norig(j) = rmeta(
cr_rec*(i-1) + 2)
322 nlen(j) = rmeta(
cr_rec*(i-1) + 3)
326 ndest(j) = rmeta2(
cr_rec*(i-1) + 1)
327 norig(j) = rmeta2(
cr_rec*(i-1) + 2)
328 nlen(j) = rmeta2(
cr_rec*(i-1) + 3)
333 if (nsw .eq. 0) dst = -1
334 if (nrw .eq. 0) src = -1
335 if (nr2w .eq. 0) src2 = -1
344 st(s)%inplace = (nsw .eq. 0)
345 call move_alloc(kidx, st(s)%keep_idx)
346 call move_alloc(sidx, st(s)%send_idx)
347 active(s) = (dst .ge. 0) .or. (src .ge. 0) .or. (src2 .ge. 0)
349 this%nsmax =
max(this%nsmax, nsw)
350 curlen = nkw + nrw + nr2w
351 this%nwrk =
max(this%nwrk, curlen)
353 deallocate(smeta, rmeta, rmeta2)
354 call move_alloc(ndest, rdest)
355 call move_alloc(norig, rorig)
356 call move_alloc(nlen, rlen)
368 call cr_final_dofs(this, rdest, rorig, rlen, nrec, recv_pe, recv_dof)
374 if (active(i)) nst = nst + 1
376 allocate(this%stage(
max(nst, 1)))
380 if (.not. active(i)) cycle
382 this%stage(j)%dst = st(i)%dst
383 this%stage(j)%src = st(i)%src
384 this%stage(j)%src2 = st(i)%src2
385 this%stage(j)%nsw = st(i)%nsw
386 this%stage(j)%nrw = st(i)%nrw
387 this%stage(j)%nr2w = st(i)%nr2w
388 this%stage(j)%nkw = st(i)%nkw
389 this%stage(j)%inplace = st(i)%inplace
390 call move_alloc(st(i)%keep_idx, this%stage(j)%keep_idx)
391 call move_alloc(st(i)%send_idx, this%stage(j)%send_idx)
393 deallocate(st, active)
399 this%stage(1)%src_sel = 1
400 this%stage(1)%dst_sel = 1
402 this%stage(j)%src_sel = sel
403 if (this%stage(j)%inplace)
then
404 this%stage(j)%dst_sel = sel
406 this%stage(j)%dst_sel = 3 - sel
416 allocate(pack_dof(
max(this%ntotal, 1)))
418 do i = 1,
size(send_pe)
419 select type (sp => send_dof(send_pe(i))%data)
421 do t = 1, send_dof(send_pe(i))%size()
428 allocate(this%pack_keep_dof(
max(this%stage(1)%nkw, 1)))
429 do j = 1, this%stage(1)%nkw
430 this%pack_keep_dof(j) = pack_dof(this%stage(1)%keep_idx(j))
432 allocate(this%pack_send_dof(
max(this%stage(1)%nsw, 1)))
433 do j = 1, this%stage(1)%nsw
434 this%pack_send_dof(j) = pack_dof(this%stage(1)%send_idx(j))
437 deallocate(this%stage(1)%keep_idx, this%stage(1)%send_idx)
439 allocate(this%pack_keep_dof(1), this%pack_send_dof(1))
442 this%nwrk =
max(this%nwrk, 1)
443 this%nsmax =
max(this%nsmax, 1)
445 deallocate(rdest, rorig, rlen)
457 integer,
intent(in) :: rdest(:), rorig(:), rlen(:), nrec
458 integer,
intent(in) :: recv_pe(:)
459 type(
stack_i4_t),
intent(inout) :: recv_dof(0:)
460 integer :: i, j, t, nfin
462 if (nrec .ne.
size(recv_pe))
then
463 call neko_error(
'gs_crystal_plan: routed record count does not ' // &
464 'match the gather-scatter schedule')
469 if (rdest(i) .ne.
pe_rank)
then
470 call neko_error(
'gs_crystal_plan: record left undelivered')
472 if (rorig(i) .lt. 0 .or. rorig(i) .ge.
pe_size)
then
473 call neko_error(
'gs_crystal_plan: record origin out of range')
475 if (rlen(i) .ne. recv_dof(rorig(i))%size())
then
476 call neko_error(
'gs_crystal_plan: routed record length does ' // &
477 'not match the gather-scatter schedule')
479 nfin = nfin + rlen(i)
483 this%nfinal_rec = nrec
484 this%nwrk =
max(this%nwrk, nfin)
485 allocate(this%unpack_dof(
max(nfin, 1)))
486 allocate(this%final_off(
max(nrec, 1)), this%final_len(
max(nrec, 1)))
490 this%final_off(i) = j
491 this%final_len(i) = rlen(i)
492 select type (rp_dof => recv_dof(rorig(i))%data)
496 this%unpack_dof(j) = rp_dof(t)