Skip to content

Commit c7fbc1d

Browse files
committed
fix(amr): non-polytropic QBMM side-state on GPU - passing amr_slots(amr_cur)%pb_f/mv_f as assumed-shape actuals made nvfortran emit a component-section data clause that dies partially-present on device (CUDA illegal address; caught by the full-suite GPU runs on both acc and omp - CPU passes only because the fine/coarse lbounds coincide); the ghost fill now selects its slot target by integer and references the slot arrays directly inside the kernels (the proven pattern of backup/update/lerp/restrict), and the pb/mv prolongation is now a device kernel reading the device-current coarse side-state (the old host-side copy would read a stale host mirror at regrid time on GPU). CPU nonpoly battery bit-identical (4/4 goldens)
1 parent a38447c commit c7fbc1d

1 file changed

Lines changed: 51 additions & 41 deletions

File tree

src/simulation/m_amr.fpp

Lines changed: 51 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -673,7 +673,7 @@ contains
673673
$:GPU_UPDATE(device='[amr_slots(amr_cur)%q_cons(i)%sf]')
674674
end do
675675
! non-polytropic QBMM: seed the block's quadrature side-state from the coarse fields
676-
if (qbmm .and. .not. polytropic) call s_amr_prolong_pbmv_host()
676+
if (qbmm .and. .not. polytropic) call s_amr_prolong_pbmv()
677677

678678
end subroutine s_populate_amr_fine
679679

@@ -912,24 +912,29 @@ contains
912912
!! push to the device. Piecewise-constant preserves the per-cell realizable quadrature set (mirroring the moments' injection).
913913
!! Called at init populate and at restart (the fine side-state is re-prolonged from the restored coarse fields - a one-time
914914
!! smoothing; q_cons is restored exactly).
915-
impure subroutine s_amr_prolong_pbmv_host()
915+
impure subroutine s_amr_prolong_pbmv()
916916

917-
integer :: fi, fj, fk, q, ib_, ci, cj, ck, rr, lo1, lo2, lo3, ox, oy, oz
917+
integer :: fi, fj, fk, q, ib_, ci, cj, ck, rr, lo1, lo2, lo3, ox, oy, oz, fm, fn, fp
918+
919+
! device kernel reading the DEVICE-current coarse side-state directly: a host-side copy
920+
! here would read a stale host mirror on GPU builds (regrid-time prolongation corruption)
918921

919922
ox = start_idx(1); oy = 0; oz = 0
920923
if (n_glb > 0) oy = start_idx(2)
921924
if (p_glb > 0) oz = start_idx(3)
922925
rr = amr_slots(amr_cur)%ref_ratio
923926
lo1 = amr_isect_lo(1); lo2 = amr_isect_lo(2); lo3 = amr_isect_lo(3)
927+
fm = amr_slots(amr_cur)%m; fn = amr_slots(amr_cur)%n; fp = amr_slots(amr_cur)%p
928+
$:GPU_PARALLEL_LOOP(collapse=5, private='[ci, cj, ck]')
924929
do ib_ = 1, nb
925930
do q = 1, nnode
926-
do fk = 0, amr_slots(amr_cur)%p
927-
ck = 0
928-
if (p_glb > 0) ck = lo3 + fk/rr - oz
929-
do fj = 0, amr_slots(amr_cur)%n
930-
cj = 0
931-
if (n_glb > 0) cj = lo2 + fj/rr - oy
932-
do fi = 0, amr_slots(amr_cur)%m
931+
do fk = 0, fp
932+
do fj = 0, fn
933+
do fi = 0, fm
934+
ck = 0
935+
if (p_glb > 0) ck = lo3 + fk/rr - oz
936+
cj = 0
937+
if (n_glb > 0) cj = lo2 + fj/rr - oy
933938
ci = lo1 + fi/rr - ox
934939
amr_slots(amr_cur)%pb_f(fi, fj, fk, q, ib_) = pb_ts(1)%sf(ci, cj, ck, q, ib_)
935940
amr_slots(amr_cur)%mv_f(fi, fj, fk, q, ib_) = mv_ts(1)%sf(ci, cj, ck, q, ib_)
@@ -938,19 +943,20 @@ contains
938943
end do
939944
end do
940945
end do
941-
$:GPU_UPDATE(device='[amr_slots(amr_cur)%pb_f, amr_slots(amr_cur)%mv_f]')
946+
$:END_GPU_PARALLEL_LOOP()
942947

943-
end subroutine s_amr_prolong_pbmv_host
948+
end subroutine s_amr_prolong_pbmv
944949

945950
!> Non-polytropic QBMM: piecewise-constant prolongation of the fine pb/mv GHOST shell from the coarse side-state (device kernel;
946951
!! interior untouched). The ghosts feed the widened-idwint conversions and the qbmm rhs over the shell, mirroring the q_cons
947-
!! ghost fill.
948-
impure subroutine s_amr_fill_fine_ghosts_pbmv(pb_c, mv_c, pb_tgt, mv_tgt)
952+
!! ghost fill. The fine target is selected by integer (1 = pb_f/mv_f, 2 = ghost_a, 3 = ghost_b) and the slot arrays are
953+
!! referenced DIRECTLY inside the kernels: passing an amr_slots(amr_cur) component as an assumed-shape actual makes nvfortran
954+
!! emit a component-section data clause that fails partially-present on device (the coarse sources pb_c/mv_c follow the proven
955+
!! pb_ts pattern).
956+
impure subroutine s_amr_fill_fine_ghosts_pbmv(pb_c, mv_c, tgt)
949957

950958
real(stp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:,1:), intent(in) :: pb_c, mv_c
951-
952-
real(stp), dimension(amr_slots(amr_cur)%idwbuff(1)%beg:,amr_slots(amr_cur)%idwbuff(2)%beg:, &
953-
& amr_slots(amr_cur)%idwbuff(3)%beg:,1:,1:), intent(inout) :: pb_tgt, mv_tgt
959+
integer, intent(in) :: tgt
954960
integer :: fi, fj, fk, q, ib_, ci, cj, ck, rr, lo1, lo2, lo3, fm, fn, fp, b1, e1, b2, e2, b3, e3, ox, oy, oz
955961
logical :: d2, d3
956962

@@ -964,27 +970,32 @@ contains
964970
b1 = amr_slots(amr_cur)%idwbuff(1)%beg; e1 = amr_slots(amr_cur)%idwbuff(1)%end
965971
b2 = amr_slots(amr_cur)%idwbuff(2)%beg; e2 = amr_slots(amr_cur)%idwbuff(2)%end
966972
b3 = amr_slots(amr_cur)%idwbuff(3)%beg; e3 = amr_slots(amr_cur)%idwbuff(3)%end
967-
$:GPU_PARALLEL_LOOP(collapse=5, private='[ci, cj, ck]')
968-
do ib_ = 1, nb
969-
do q = 1, nnode
970-
do fk = b3, e3
971-
do fj = b2, e2
972-
do fi = b1, e1
973-
if (.not. (fi >= 0 .and. fi <= fm .and. fj >= 0 .and. fj <= fn .and. fk >= 0 .and. fk <= fp)) then
974-
ck = 0
975-
if (d3) ck = lo3 + floor(real(fk, wp)/real(rr, wp)) - oz
976-
cj = 0
977-
if (d2) cj = lo2 + floor(real(fj, wp)/real(rr, wp)) - oy
978-
ci = lo1 + floor(real(fi, wp)/real(rr, wp)) - ox
979-
pb_tgt(fi, fj, fk, q, ib_) = pb_c(ci, cj, ck, q, ib_)
980-
mv_tgt(fi, fj, fk, q, ib_) = mv_c(ci, cj, ck, q, ib_)
981-
end if
973+
#:for TGT, SFX in [(1, 'f'), (2, 'ghost_a'), (3, 'ghost_b')]
974+
if (tgt == ${TGT}$) then
975+
$:GPU_PARALLEL_LOOP(collapse=5, private='[ci, cj, ck]')
976+
do ib_ = 1, nb
977+
do q = 1, nnode
978+
do fk = b3, e3
979+
do fj = b2, e2
980+
do fi = b1, e1
981+
if (.not. (fi >= 0 .and. fi <= fm .and. fj >= 0 .and. fj <= fn .and. fk >= 0 .and. fk <= fp)) &
982+
& then
983+
ck = 0
984+
if (d3) ck = lo3 + floor(real(fk, wp)/real(rr, wp)) - oz
985+
cj = 0
986+
if (d2) cj = lo2 + floor(real(fj, wp)/real(rr, wp)) - oy
987+
ci = lo1 + floor(real(fi, wp)/real(rr, wp)) - ox
988+
amr_slots(amr_cur)%pb_${SFX}$ (fi, fj, fk, q, ib_) = pb_c(ci, cj, ck, q, ib_)
989+
amr_slots(amr_cur)%mv_${SFX}$ (fi, fj, fk, q, ib_) = mv_c(ci, cj, ck, q, ib_)
990+
end if
991+
end do
992+
end do
982993
end do
983994
end do
984995
end do
985-
end do
986-
end do
987-
$:END_GPU_PARALLEL_LOOP()
996+
$:END_GPU_PARALLEL_LOOP()
997+
end if
998+
#:endfor
988999

9891000
end subroutine s_amr_fill_fine_ghosts_pbmv
9901001

@@ -1687,8 +1698,7 @@ contains
16871698
16881699
! non-polytropic QBMM: prolong the block's pb/mv ghost shell from the coarse stage-entry
16891700
! side-state (its rhs is cell-local, so ghosts only feed the widened-idwint conversions)
1690-
if (qbmm .and. .not. polytropic) call s_amr_fill_fine_ghosts_pbmv(pb_in, mv_in, amr_slots(amr_cur)%pb_f, &
1691-
& amr_slots(amr_cur)%mv_f)
1701+
if (qbmm .and. .not. polytropic) call s_amr_fill_fine_ghosts_pbmv(pb_in, mv_in, 1)
16921702

16931703
! step-entry backup for the SSP-RK combination (device copy over the current buffered extents)
16941704
if (s == 1) then
@@ -1769,8 +1779,8 @@ contains
17691779
call s_amr_fill_fine_ghosts(q_new, amr_slots(amr_cur)%q_ghost_b)
17701780
! non-polytropic QBMM: the pb/mv ghost shell gets the same two-source time-lerp treatment
17711781
if (qbmm .and. .not. polytropic) then
1772-
call s_amr_fill_fine_ghosts_pbmv(pb_old, mv_old, amr_slots(amr_cur)%pb_ghost_a, amr_slots(amr_cur)%mv_ghost_a)
1773-
call s_amr_fill_fine_ghosts_pbmv(pb_in, mv_in, amr_slots(amr_cur)%pb_ghost_b, amr_slots(amr_cur)%mv_ghost_b)
1782+
call s_amr_fill_fine_ghosts_pbmv(pb_old, mv_old, 2)
1783+
call s_amr_fill_fine_ghosts_pbmv(pb_in, mv_in, 3)
17741784
end if
17751785
call s_amr_zero_fine_registers()
17761786

@@ -2510,7 +2520,7 @@ contains
25102520
! non-polytropic QBMM: prolong the side-state from coarse (piecewise-constant),
25112521
! then overwrite the overlap with the old blocks' fine data (same index shift)
25122522
if (qbmm .and. .not. polytropic) then
2513-
call s_amr_prolong_pbmv_host()
2523+
call s_amr_prolong_pbmv()
25142524
do kk = 1, old_np
25152525
if (.not. old_owns(kk)) cycle
25162526
sh = 2*(amr_isect_lo - old_ilo(:,kk))
@@ -2845,7 +2855,7 @@ contains
28452855
if (qbmm .and. .not. polytropic) then
28462856
do k = 1, amr_num_blocks
28472857
call s_amr_select_slot(k)
2848-
if (amr_owns_all(k)) call s_amr_prolong_pbmv_host()
2858+
if (amr_owns_all(k)) call s_amr_prolong_pbmv()
28492859
end do
28502860
end if
28512861
call s_amr_select_slot(1)

0 commit comments

Comments
 (0)