Skip to content

Commit 2b309ec

Browse files
author
Jesse Lentz
committed
Avoid temporary buffer when default dim_order is used
1 parent 693d1ea commit 2b309ec

1 file changed

Lines changed: 85 additions & 37 deletions

File tree

interpolator/include/interpolator.inc

Lines changed: 85 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1423,13 +1423,13 @@ type(interpolate_type), intent(inout) :: clim_type
14231423
character(len=*) , intent(in) :: field_name
14241424
type(time_type) , intent(in) :: Time
14251425
real(FMS_INTP_KIND_), dimension(:,:,:), intent(in) :: phalf
1426-
real(FMS_INTP_KIND_), dimension(:,:,:,:), intent(out) :: interp_data
1426+
real(FMS_INTP_KIND_), dimension(:,:,:,:), intent(out), target :: interp_data
14271427
integer , intent(in) , optional :: is,js
14281428
character(len=*) , intent(out), optional :: clim_units
14291429
integer , intent(in), optional :: dim_order(4)
14301430
integer :: taum, taup, ilon
1431-
real(FMS_INTP_KIND_), allocatable :: hinterp_data(:,:,:,:), p_fact(:,:), col_data(:,:,:), &
1432-
interp_buf(:,:,:,:), phalf_diff(:,:,:)
1431+
real(FMS_INTP_KIND_), allocatable :: hinterp_data(:,:,:,:), p_fact(:,:), col_data(:,:,:), phalf_diff(:,:,:)
1432+
real(FMS_INTP_KIND_), pointer :: interp_buf(:,:,:,:)
14331433
real(FMS_INTP_KIND_) :: pclim(size(clim_type%FMS_INTP_TYPE_%halflevs(:)))
14341434
integer :: istart,iend,jstart,jend
14351435
logical :: result, found
@@ -1445,8 +1445,10 @@ integer :: i, j, k, n
14451445
integer :: ni, nj, nk
14461446
integer :: nlevs, nfields
14471447
integer :: dim_map(4) !< x, y, z, field
1448+
logical :: use_buf
14481449
character(len=256) :: err_msg
14491450

1451+
integer, parameter :: dim_map_default(4) = [1, 2, 3, 4]
14501452
integer, parameter :: lkind=FMS_INTP_KIND_
14511453

14521454
if (.not. module_is_initialized .or. .not. allocated(clim_type%FMS_INTP_TYPE_%lon)) &
@@ -1455,9 +1457,11 @@ if (.not. module_is_initialized .or. .not. allocated(clim_type%FMS_INTP_TYPE_%lo
14551457
if (present(dim_order)) then
14561458
call inverse_permutation(dim_order, dim_map)
14571459
else
1458-
dim_map = [1, 2, 3, 4]
1460+
dim_map = dim_map_default
14591461
endif
14601462

1463+
use_buf = any(dim_map.ne.dim_map_default)
1464+
14611465
ni = size(interp_data, dim_map(1))
14621466
nj = size(interp_data, dim_map(2))
14631467
nk = size(interp_data, dim_map(3))
@@ -1467,9 +1471,15 @@ nfields = size(clim_type%field_name)
14671471
allocate(hinterp_data(ni,nj,nlevs,nfields))
14681472
allocate(p_fact(ni,nj))
14691473
allocate(col_data(ni,nj,nfields))
1470-
allocate(interp_buf(ni,nj,nk,nfields))
14711474
allocate(phalf_diff(ni,nj,nk))
14721475

1476+
if (use_buf) then
1477+
allocate(interp_buf(ni,nj,nk,nfields))
1478+
call mpp_error(NOTE, "interpolator_4D: Using temporary buffer")
1479+
else
1480+
interp_buf => interp_data
1481+
endif
1482+
14731483
do n=2,nfields
14741484
if (clim_type%vert_interp(n) /= clim_type%vert_interp(n-1) .or. &
14751485
clim_type%out_of_bounds(n) /= clim_type%out_of_bounds(n-1)) then
@@ -1851,7 +1861,10 @@ enddo
18511861
end select
18521862
end do
18531863

1854-
interp_data = reshape(interp_buf, shape(interp_data), order=dim_map)
1864+
if (use_buf) then
1865+
interp_data = reshape(interp_buf, shape(interp_data), order=dim_map)
1866+
deallocate(interp_buf)
1867+
endif
18551868

18561869
if( .not. found_field) then !field name is not in interpolator file.ERROR.
18571870
call mpp_error(FATAL,"Interpolator: the field name is not contained in this &
@@ -1913,13 +1926,13 @@ type(interpolate_type), intent(inout) :: clim_type
19131926
character(len=*) , intent(in) :: field_name
19141927
type(time_type) , intent(in) :: Time
19151928
real(FMS_INTP_KIND_), dimension(:,:,:), intent(in) :: phalf
1916-
real(FMS_INTP_KIND_), dimension(:,:,:), intent(out) :: interp_data
1929+
real(FMS_INTP_KIND_), dimension(:,:,:), intent(out), target :: interp_data
19171930
integer , intent(in) , optional :: is,js
19181931
character(len=*) , intent(out), optional :: clim_units
19191932
integer , intent(in), optional :: dim_order(3)
19201933
integer :: taum, taup, ilon
1921-
real(FMS_INTP_KIND_), allocatable :: hinterp_data(:,:,:), p_fact(:,:), col_data(:,:), &
1922-
interp_buf(:,:,:), phalf_diff(:,:,:)
1934+
real(FMS_INTP_KIND_), allocatable :: hinterp_data(:,:,:), p_fact(:,:), col_data(:,:), phalf_diff(:,:,:)
1935+
real(FMS_INTP_KIND_), pointer :: interp_buf(:,:,:)
19231936
real(FMS_INTP_KIND_) :: pclim(size(clim_type%FMS_INTP_TYPE_%halflevs(:)))
19241937
integer :: istart,iend,jstart,jend
19251938
logical :: result, found
@@ -1935,8 +1948,10 @@ integer :: i, j, k, n
19351948
integer :: ni, nj, nk
19361949
integer :: nlevs, nfields
19371950
integer :: dim_map(3) !< x, y, z
1951+
logical :: use_buf
19381952
character(len=256) :: err_msg
19391953

1954+
integer, parameter :: dim_map_default(3) = [1, 2, 3]
19401955
integer, parameter :: lkind=FMS_INTP_KIND_
19411956

19421957
if (.not. module_is_initialized .or. .not. allocated(clim_type%FMS_INTP_TYPE_%lon)) &
@@ -1945,9 +1960,11 @@ if (.not. module_is_initialized .or. .not. allocated(clim_type%FMS_INTP_TYPE_%lo
19451960
if (present(dim_order)) then
19461961
call inverse_permutation(dim_order, dim_map)
19471962
else
1948-
dim_map = [1, 2, 3]
1963+
dim_map = dim_map_default
19491964
endif
19501965

1966+
use_buf = any(dim_map.ne.dim_map_default)
1967+
19511968
ni = size(interp_data, dim_map(1))
19521969
nj = size(interp_data, dim_map(2))
19531970
nk = size(interp_data, dim_map(3))
@@ -1957,9 +1974,15 @@ nfields = size(clim_type%field_name)
19571974
allocate(hinterp_data(ni,nj,nlevs))
19581975
allocate(p_fact(ni,nj))
19591976
allocate(col_data(ni,nj))
1960-
allocate(interp_buf(ni,nj,nk))
19611977
allocate(phalf_diff(ni,nj,nk))
19621978

1979+
if (use_buf) then
1980+
allocate(interp_buf(ni,nj,nk))
1981+
call mpp_error(NOTE, "interpolator_3D: Using temporary buffer")
1982+
else
1983+
interp_buf => interp_data
1984+
endif
1985+
19631986
istart = 1
19641987
if (present(is)) istart = is
19651988
iend = istart - 1 + ni
@@ -2313,8 +2336,10 @@ end select
23132336
endif !field_name
23142337
enddo !End of i loop
23152338

2316-
interp_data = reshape(interp_buf, shape(interp_data), order=dim_map)
2317-
2339+
if (use_buf) then
2340+
interp_data = reshape(interp_buf, shape(interp_data), order=dim_map)
2341+
deallocate(interp_buf)
2342+
endif
23182343

23192344
if( .not. found_field) then !field name is not in interpolator file.ERROR.
23202345
call mpp_error(FATAL,"Interpolator: the field name is not contained in this &
@@ -2370,7 +2395,7 @@ subroutine INTERPOLATOR_2D_(clim_type, Time, interp_data, field_name, is, js, cl
23702395
type(interpolate_type), intent(inout) :: clim_type
23712396
character(len=*) , intent(in) :: field_name
23722397
type(time_type) , intent(in) :: Time
2373-
real(FMS_INTP_KIND_), dimension(:,:), intent(out) :: interp_data
2398+
real(FMS_INTP_KIND_), dimension(:,:), intent(out), target :: interp_data
23742399
integer , intent(in) , optional :: is,js
23752400
character(len=*) , intent(out), optional :: clim_units
23762401
integer , intent(in), optional :: dim_order(2)
@@ -2392,6 +2417,7 @@ integer :: nlevs, nfields
23922417
integer :: dim_map(2) !< x, y
23932418
character(len=256) :: err_msg
23942419

2420+
integer, parameter :: dim_map_default(2) = [1, 2]
23952421
integer, parameter :: lkind=FMS_INTP_KIND_
23962422

23972423
if (.not. module_is_initialized .or. .not. allocated(clim_type%FMS_INTP_TYPE_%lon)) &
@@ -2400,7 +2426,7 @@ if (.not. module_is_initialized .or. .not. allocated(clim_type%FMS_INTP_TYPE_%lo
24002426
if (present(dim_order)) then
24012427
call inverse_permutation(dim_order, dim_map)
24022428
else
2403-
dim_map = [1, 2]
2429+
dim_map = dim_map_default
24042430
endif
24052431

24062432
ni = size(interp_data, dim_map(1))
@@ -2602,9 +2628,6 @@ if ( .not. clim_type%separate_time_vary_calc) then
26022628
clim_type%indexp(i)+clim_type%climatology(i)*12,i,Time)
26032629
endif
26042630

2605-
2606-
2607-
26082631
else ! We are within a climatology data set
26092632

26102633
if (taum /= clim_type%time_init(i,1) .or. &
@@ -2677,8 +2700,6 @@ if ( .not. clim_type%separate_time_vary_calc) then
26772700

26782701
endif ! (.not. separate_time_vary_calc)
26792702

2680-
2681-
26822703
select case(clim_type%TIME_FLAG)
26832704
case (LINEAR)
26842705
hinterp_data = (1._lkind-clim_type%FMS_INTP_TYPE_%tweight)*&
@@ -2775,20 +2796,23 @@ subroutine INTERPOLATOR_4D_NO_TIME_AXIS_(clim_type, phalf, interp_data, field_na
27752796
type(interpolate_type), intent(inout) :: clim_type
27762797
character(len=*) , intent(in) :: field_name
27772798
real(FMS_INTP_KIND_), dimension(:,:,:), intent(in) :: phalf
2778-
real(FMS_INTP_KIND_), dimension(:,:,:,:), intent(out) :: interp_data
2799+
real(FMS_INTP_KIND_), dimension(:,:,:,:), intent(out), target :: interp_data
27792800
integer , intent(in) , optional :: is,js
27802801
character(len=*) , intent(out), optional :: clim_units
27812802
integer , intent(in), optional :: dim_order(4)
27822803
integer :: ilon
2783-
real(FMS_INTP_KIND_), allocatable :: hinterp_data(:,:,:,:), p_fact(:,:), interp_buf(:,:,:,:), phalf_diff(:,:,:)
2804+
real(FMS_INTP_KIND_), allocatable :: hinterp_data(:,:,:,:), p_fact(:,:), phalf_diff(:,:,:)
2805+
real(FMS_INTP_KIND_), pointer :: interp_buf(:,:,:,:)
27842806
real(FMS_INTP_KIND_) :: pclim(size(clim_type%FMS_INTP_TYPE_%halflevs(:)))
27852807
integer :: istart,iend,jstart,jend
27862808
logical :: found_field=.false.
27872809
integer :: i, j, k, n
27882810
integer :: ni, nj, nk
27892811
integer :: nlevs, nfields
27902812
integer :: dim_map(4) !< x, y, z, field
2813+
logical :: use_buf
27912814

2815+
integer, parameter :: dim_map_default(4) = [1, 2, 3, 4]
27922816
integer, parameter :: lkind=FMS_INTP_KIND_
27932817

27942818
if (.not. module_is_initialized .or. .not. allocated(clim_type%FMS_INTP_TYPE_%lon)) &
@@ -2797,9 +2821,11 @@ if (.not. module_is_initialized .or. .not. allocated(clim_type%FMS_INTP_TYPE_%lo
27972821
if (present(dim_order)) then
27982822
call inverse_permutation(dim_order, dim_map)
27992823
else
2800-
dim_map = [1, 2, 3, 4]
2824+
dim_map = dim_map_default
28012825
endif
28022826

2827+
use_buf = any(dim_map.ne.dim_map_default)
2828+
28032829
ni = size(interp_data, dim_map(1))
28042830
nj = size(interp_data, dim_map(2))
28052831
nk = size(interp_data, dim_map(3))
@@ -2808,9 +2834,15 @@ nfields = size(clim_type%field_name)
28082834

28092835
allocate(hinterp_data(ni,nj,nlevs,nfields))
28102836
allocate(p_fact(ni,nj))
2811-
allocate(interp_buf(ni,nj,nk,nfields))
28122837
allocate(phalf_diff(ni,nj,nk))
28132838

2839+
if (use_buf) then
2840+
allocate(interp_buf(ni,nj,nk,nfields))
2841+
call mpp_error(NOTE, "interpolator_4D_no_time_axis: Using temporary buffer")
2842+
else
2843+
interp_buf => interp_data
2844+
endif
2845+
28142846
do n=2,nfields
28152847
if (clim_type%vert_interp(n) /= clim_type%vert_interp(n-1) .or. &
28162848
clim_type%out_of_bounds(n) /= clim_type%out_of_bounds(n-1)) then
@@ -2911,7 +2943,10 @@ enddo
29112943
end select
29122944
end do
29132945

2914-
interp_data = reshape(interp_buf, shape(interp_data), order=dim_map)
2946+
if (use_buf) then
2947+
interp_data = reshape(interp_buf, shape(interp_data), order=dim_map)
2948+
deallocate(interp_buf)
2949+
endif
29152950

29162951
if( .not. found_field) then !field name is not in interpolator file.ERROR.
29172952
call mpp_error(FATAL,"Interpolator: the field name is not contained in this &
@@ -2964,20 +2999,23 @@ subroutine INTERPOLATOR_3D_NO_TIME_AXIS_(clim_type, phalf, interp_data, field_na
29642999
type(interpolate_type), intent(inout) :: clim_type
29653000
character(len=*) , intent(in) :: field_name
29663001
real(FMS_INTP_KIND_), dimension(:,:,:), intent(in) :: phalf
2967-
real(FMS_INTP_KIND_), dimension(:,:,:), intent(out) :: interp_data
3002+
real(FMS_INTP_KIND_), dimension(:,:,:), intent(out), target :: interp_data
29683003
integer , intent(in) , optional :: is,js
29693004
character(len=*) , intent(out), optional :: clim_units
29703005
integer , intent(in), optional :: dim_order(3)
29713006
integer :: ilon !< No description
2972-
real(FMS_INTP_KIND_), allocatable :: hinterp_data(:,:,:), p_fact(:,:), interp_buf(:,:,:), phalf_diff(:,:,:)
3007+
real(FMS_INTP_KIND_), allocatable :: hinterp_data(:,:,:), p_fact(:,:), phalf_diff(:,:,:)
3008+
real(FMS_INTP_KIND_), pointer :: interp_buf(:,:,:)
29733009
real(FMS_INTP_KIND_) :: pclim(size(clim_type%FMS_INTP_TYPE_%halflevs(:))) !< No description
29743010
integer :: istart,iend,jstart,jend !< No description
29753011
logical :: found_field=.false. !< No description
29763012
integer :: i, j, k !< No description
29773013
integer :: ni, nj, nk
29783014
integer :: nlevs, nfields
29793015
integer :: dim_map(3) !< x, y, z
3016+
logical :: use_buf
29803017

3018+
integer, parameter :: dim_map_default(3) = [1, 2, 3]
29813019
integer, parameter :: lkind=FMS_INTP_KIND_
29823020

29833021
if (.not. module_is_initialized .or. .not. allocated(clim_type%FMS_INTP_TYPE_%lon)) &
@@ -2986,9 +3024,11 @@ if (.not. module_is_initialized .or. .not. allocated(clim_type%FMS_INTP_TYPE_%lo
29863024
if (present(dim_order)) then
29873025
call inverse_permutation(dim_order, dim_map)
29883026
else
2989-
dim_map = [1, 2, 3]
3027+
dim_map = dim_map_default
29903028
endif
29913029

3030+
use_buf = any(dim_map.ne.dim_map_default)
3031+
29923032
ni = size(interp_data, dim_map(1))
29933033
nj = size(interp_data, dim_map(2))
29943034
nk = size(interp_data, dim_map(3))
@@ -2997,9 +3037,15 @@ nfields = size(clim_type%field_name)
29973037

29983038
allocate(hinterp_data(ni,nj,nlevs))
29993039
allocate(p_fact(ni,nj))
3000-
allocate(interp_buf(ni,nj,nk))
30013040
allocate(phalf_diff(ni,nj,nk))
30023041

3042+
if (use_buf) then
3043+
allocate(interp_buf(ni,nj,nk))
3044+
call mpp_error(NOTE, "interpolator_3D_no_time_axis: Using temporary buffer")
3045+
else
3046+
interp_buf => interp_data
3047+
endif
3048+
30033049
istart = 1
30043050
if (present(is)) istart = is
30053051
iend = istart - 1 + ni
@@ -3074,7 +3120,10 @@ select case(clim_type%mr(i))
30743120
interp_buf(:,:,:) = interp_buf(:,:,:)*phalf_diff
30753121
end select
30763122

3077-
interp_data = reshape(interp_buf, shape(interp_data), order=dim_map)
3123+
if (use_buf) then
3124+
interp_data = reshape(interp_buf, shape(interp_data), order=dim_map)
3125+
deallocate(interp_buf)
3126+
endif
30783127

30793128
endif !field_name
30803129
enddo !End of i loop
@@ -3120,34 +3169,33 @@ subroutine INTERPOLATOR_2D_NO_TIME_AXIS_(clim_type, interp_data, field_name, is,
31203169

31213170
type(interpolate_type), intent(inout) :: clim_type
31223171
character(len=*) , intent(in) :: field_name
3123-
real(FMS_INTP_KIND_), dimension(:,:), intent(out) :: interp_data
3172+
real(FMS_INTP_KIND_), dimension(:,:), intent(out), target :: interp_data
31243173
integer , intent(in) , optional :: is,js
31253174
character(len=*) , intent(out), optional :: clim_units
31263175
integer , intent(in), optional :: dim_order(2)
3127-
real(FMS_INTP_KIND_), allocatable :: hinterp_data(:,:)
31283176
integer :: istart,iend,jstart,jend
31293177
logical :: found_field=.false.
31303178
integer :: i
31313179
integer :: ni, nj
31323180
integer :: nlevs, nfields
31333181
integer :: dim_map(2) !< x, y
31343182

3183+
integer, parameter :: dim_map_default(2) = [1, 2]
3184+
31353185
if (.not. module_is_initialized .or. .not. allocated(clim_type%FMS_INTP_TYPE_%lon)) &
31363186
call mpp_error(FATAL, "interpolator_2D_no_time_axis : You must call interpolator_init before calling interpolator")
31373187

31383188
if (present(dim_order)) then
31393189
call inverse_permutation(dim_order, dim_map)
31403190
else
3141-
dim_map = [1, 2]
3191+
dim_map = dim_map_default
31423192
endif
31433193

31443194
ni = size(interp_data, dim_map(1))
31453195
nj = size(interp_data, dim_map(2))
31463196
nlevs = size(clim_type%FMS_INTP_TYPE_%levs)
31473197
nfields = size(clim_type%field_name)
31483198

3149-
allocate(hinterp_data(ni,nj))
3150-
31513199
istart = 1
31523200
if (present(is)) istart = is
31533201
iend = istart - 1 + ni
@@ -3166,8 +3214,8 @@ do i= 1,nfields
31663214
clim_units = chomp(clim_units)
31673215
endif
31683216

3169-
hinterp_data = clim_type%FMS_INTP_TYPE_%data5d(istart:iend,jstart:jend,1,1,i)
3170-
interp_data = reshape(hinterp_data, shape(interp_data), order=dim_map)
3217+
interp_data = reshape(clim_type%FMS_INTP_TYPE_%data5d(istart:iend,jstart:jend,1,1,i), &
3218+
shape(interp_data), order=dim_map)
31713219

31723220
endif !field_name
31733221
enddo !End of i loop

0 commit comments

Comments
 (0)