NOAA-GFDL/GFDL_atmos_cubed_sphere

"bug" in send_data call

Closed this issue · 1 comments

Describe the bug
In a future FMS release, the send_data interface will be updated to include the CONTIGUOUS keyword for the field_data:
https://github.com/NOAA-GFDL/FMS/blob/5ce479028dbfab04fe64501b11f2516e6717f5d7/diag_manager/diag_manager.F90#L1580-L1583

    CLASS(*), DIMENSION(:,:,:), INTENT(in), TARGET, CONTIGUOUS :: field

After this update, AM4 is crashing with intel in debug mode with:

forrtl: severe (408): fort: (2): Subscript #4 of the array Q has value 27 which is greater than the upper bound of 26

Image              PC                Routine            Line        Source            
fms_cm4p12_2023.0  000000000FA59D80  Unknown               Unknown  Unknown
fms_cm4p12_2023.0  0000000001D67D48  fv_diagnostics_mo        3569  fv_diagnostics.F90
fms_cm4p12_2023.0  0000000000B2DEBD  atmosphere_mod_mp        1189  atmosphere.F90
fms_cm4p12_2023.0  0000000000A3769E  atmos_model_mod_m        1085  atmos_model.F90
fms_cm4p12_2023.0  00000000004119FF  MAIN__                    947  coupler_main.F90
fms_cm4p12_2023.0  000000000040DCAE  Unknown               Unknown  Unknown
fms_cm4p12_2023.0  000000000FB33B4F  Unknown               Unknown  Unknown
fms_cm4p12_2023.0  000000000040DB9A  Unknown               Unknown  Unknown

This is where it crashes:

if (id_tracer(itrac) > 0 .and. itrac.gt.nq) then
used = send_data (id_tracer(itrac), Atm(n)%qdiag(isc:iec,jsc:jec,:,itrac), Time )
else
used = send_data (id_tracer(itrac), Atm(n)%q(isc:iec,jsc:jec,:,itrac), Time )
endif

In the case that I was running,
Atm(n)%ncnst=27
The ubound of the fourth dimension of Atm(n)%qdiag is 27 and for Atm(n)%q is 26
nq = size (Atm(n)%q,4)

so in the case where itrac is 27 and id_tracer(itrac) is less than 0 (because that tracer is not in the diag_table) it will go into:

used = send_data (id_tracer(itrac), Atm(n)%q(isc:iec,jsc:jec,:,itrac), Time )

and crash with the out of the bounds error.

This crash does not happen when send_data does not have the CONTIGUOUS keyword because the compiler does not check the bounds. It doesn't affect anything because the id_tracer(27) is not in the diag_table so send_data will not do anything.

To Reproduce
Run AM4 on gaea in intel 21 debug mode with the send_data interface updated to include the CONTIGUOUS keyword

Expected behavior
I think we should modify the code to do:

          if (itrac.gt.nq) then
            used = send_data (id_tracer(itrac), Atm(n)%qdiag(isc:iec,jsc:jec,:,itrac), Time )
          else
            used = send_data (id_tracer(itrac), Atm(n)%q(isc:iec,jsc:jec,:,itrac), Time )
          endif

the id_tracer(itrac) > 0 is redundant because if id_tracer(itrac) <= 0, send_data will simply return and not do anything.
https://github.com/NOAA-GFDL/FMS/blob/5ce479028dbfab04fe64501b11f2516e6717f5d7/diag_manager/diag_manager.F90#L1635-L1640

System Environment
Describe the system environment, include:
GAEA, intel21 debug mode

Additional context
The behavior can be reproduced with the following program:

real :: var(10,10,10,10)                                                                                                
integer :: i                                                                                                            
                                                                                                                       
do i = 1, 11                                                                                                            
  call do_stuff(var(2:8,2:8,:,i))                                                                                      
enddo                                                                                                                  
contains                                                                                                                
                                                                                                                       
subroutine do_stuff(field)                                                                                              
  CLASS(*), DIMENSION(:,:,:), contiguous, target, INTENT(in) :: field                                                  
end subroutine do_stuff

If i compile (with the debug configuration) and run the program crashes, but if I remove the contiguous keyword it will run successfully.

Fixed in PR #250