@@ -181,20 +181,23 @@ end function fitpack_polar_boundary
181181 interface FP_COMM_SIZE
182182 module procedure FP_REAL_COMM_SIZE_1D
183183 module procedure FP_REAL_COMM_SIZE_2D
184+ module procedure FP_REAL_COMM_SIZE_3D
184185 module procedure FP_SIZE_COMM_SIZE_1D
185186 end interface FP_COMM_SIZE
186187
187- !> Pack allocatable 1D arrays into communication buffer
188+ !> Pack allocatable arrays into communication buffer
188189 interface FP_COMM_PACK
189190 module procedure FP_REAL_COMM_PACK_1D
190191 module procedure FP_REAL_COMM_PACK_2D
192+ module procedure FP_REAL_COMM_PACK_3D
191193 module procedure FP_SIZE_COMM_PACK_1D
192194 end interface FP_COMM_PACK
193195
194- !> Expand communication buffer into allocatable 1D arrays
196+ !> Expand communication buffer into allocatable arrays
195197 interface FP_COMM_EXPAND
196198 module procedure FP_REAL_COMM_EXPAND_1D
197199 module procedure FP_REAL_COMM_EXPAND_2D
200+ module procedure FP_REAL_COMM_EXPAND_3D
198201 module procedure FP_SIZE_COMM_EXPAND_1D
199202 end interface FP_COMM_EXPAND
200203
@@ -18325,6 +18328,18 @@ pure integer(FP_SIZE) function FP_REAL_COMM_SIZE_2D(array)
1832518328 end if
1832618329 end function FP_REAL_COMM_SIZE_2D
1832718330
18331+ !> Calculate storage size for 3D real(FP_REAL) allocatable array
18332+ pure integer(FP_SIZE) function FP_REAL_COMM_SIZE_3D(array)
18333+ real(FP_REAL), allocatable, intent(in) :: array(:,:,:)
18334+ integer(FP_SIZE) :: n
18335+
18336+ FP_REAL_COMM_SIZE_3D = rank(array) ! Header (3 dimensions)
18337+ if (allocated(array)) then
18338+ n = size(array, kind=FP_SIZE)
18339+ FP_REAL_COMM_SIZE_3D = FP_REAL_COMM_SIZE_3D + FP_RCOMMS_PER_BITS(n * storage_size(array))
18340+ end if
18341+ end function FP_REAL_COMM_SIZE_3D
18342+
1832818343 !> Calculate storage size for 1D integer(FP_SIZE) allocatable array
1832918344 pure integer(FP_SIZE) function FP_SIZE_COMM_SIZE_1D(array)
1833018345 integer(FP_SIZE), allocatable, intent(in) :: array(:)
@@ -18384,6 +18399,33 @@ pure subroutine FP_REAL_COMM_PACK_2D(array, buffer)
1838418399 end if
1838518400 end subroutine FP_REAL_COMM_PACK_2D
1838618401
18402+ !> Pack 3D real(FP_REAL) allocatable array into communication buffer
18403+ pure subroutine FP_REAL_COMM_PACK_3D(array, buffer)
18404+ real(FP_REAL), allocatable, intent(in) :: array(:,:,:)
18405+ real(FP_COMM), intent(out) :: buffer(:)
18406+
18407+ integer(FP_SIZE) :: bnd(2, 3), ndoubles
18408+ integer(FP_SIZE), parameter :: header = 3
18409+
18410+ if (allocated(array)) then
18411+ bnd(1, 1) = lbound(array, 1, FP_SIZE)
18412+ bnd(2, 1) = ubound(array, 1, FP_SIZE)
18413+ bnd(1, 2) = lbound(array, 2, FP_SIZE)
18414+ bnd(2, 2) = ubound(array, 2, FP_SIZE)
18415+ bnd(1, 3) = lbound(array, 3, FP_SIZE)
18416+ bnd(2, 3) = ubound(array, 3, FP_SIZE)
18417+ else
18418+ bnd = FP_NOT_ALLOC
18419+ end if
18420+
18421+ buffer(1:header) = transfer(bnd, buffer(1:header), int(header))
18422+
18423+ if (all(bnd /= FP_NOT_ALLOC)) then
18424+ ndoubles = FP_RCOMMS_PER_BITS(size(array, kind=FP_SIZE) * storage_size(array))
18425+ buffer(header+1:header+ndoubles) = transfer(array, buffer(header+1:header+ndoubles), int(ndoubles))
18426+ end if
18427+ end subroutine FP_REAL_COMM_PACK_3D
18428+
1838718429 !> Pack 1D integer(FP_SIZE) allocatable array into communication buffer
1838818430 pure subroutine FP_SIZE_COMM_PACK_1D(array, buffer)
1838918431 integer(FP_SIZE), allocatable, intent(in) :: array(:)
@@ -18419,7 +18461,13 @@ pure subroutine FP_REAL_COMM_EXPAND_1D(array, buffer)
1841918461 if (all(bnd /= FP_NOT_ALLOC)) then
1842018462 allocate(array(bnd(1):bnd(2)))
1842118463 n = FP_RCOMMS_PER_BITS(size(array, kind=FP_SIZE) * storage_size(array))
18464+ #if defined(__INTEL_COMPILER) || defined(__INTEL_LLVM_COMPILER)
18465+ ! Intel: avoid transfer() — temporary overflows the stack for large arrays.
18466+ ! FP_REAL == FP_COMM (both c_double), so direct assignment is valid.
18467+ array(:) = buffer(header+1:header+n)
18468+ #else
1842218469 array = transfer(buffer(header+1:header+n), array)
18470+ #endif
1842318471 end if
1842418472 end subroutine FP_REAL_COMM_EXPAND_1D
1842518473
@@ -18436,10 +18484,39 @@ pure subroutine FP_REAL_COMM_EXPAND_2D(array, buffer)
1843618484 if (all(bnd /= FP_NOT_ALLOC)) then
1843718485 allocate(array(bnd(1,1):bnd(2,1), bnd(1,2):bnd(2,2)))
1843818486 n = FP_RCOMMS_PER_BITS(size(array, kind=FP_SIZE) * storage_size(array))
18487+ #if defined(__INTEL_COMPILER) || defined(__INTEL_LLVM_COMPILER)
18488+ ! Intel: avoid transfer() — temporary overflows the stack for large arrays.
18489+ ! FP_REAL == FP_COMM (both c_double), so reshape buffer directly.
18490+ array(:,:) = reshape(buffer(header+1:header+n), shape(array))
18491+ #else
1843918492 array = reshape(transfer(buffer(header+1:header+n), array, size(array)), shape(array))
18493+ #endif
1844018494 end if
1844118495 end subroutine FP_REAL_COMM_EXPAND_2D
1844218496
18497+ !> Expand communication buffer into 3D real(FP_REAL) allocatable array
18498+ pure subroutine FP_REAL_COMM_EXPAND_3D(array, buffer)
18499+ real(FP_REAL), allocatable, intent(out) :: array(:,:,:)
18500+ real(FP_COMM), intent(in) :: buffer(:)
18501+
18502+ integer(FP_SIZE) :: bnd(2, 3), n
18503+ integer(FP_SIZE), parameter :: header = 3
18504+
18505+ bnd = reshape(transfer(buffer(:header), bnd), shape(bnd))
18506+
18507+ if (all(bnd /= FP_NOT_ALLOC)) then
18508+ allocate(array(bnd(1,1):bnd(2,1), bnd(1,2):bnd(2,2), bnd(1,3):bnd(2,3)))
18509+ n = FP_RCOMMS_PER_BITS(size(array, kind=FP_SIZE) * storage_size(array))
18510+ #if defined(__INTEL_COMPILER) || defined(__INTEL_LLVM_COMPILER)
18511+ ! Intel: avoid transfer() — temporary overflows the stack for large arrays.
18512+ ! FP_REAL == FP_COMM (both c_double), so reshape buffer directly.
18513+ array(:,:,:) = reshape(buffer(header+1:header+n), shape(array))
18514+ #else
18515+ array = reshape(transfer(buffer(header+1:header+n), array, size(array)), shape(array))
18516+ #endif
18517+ end if
18518+ end subroutine FP_REAL_COMM_EXPAND_3D
18519+
1844318520 !> Expand communication buffer into 1D integer(FP_SIZE) allocatable array
1844418521 pure subroutine FP_SIZE_COMM_EXPAND_1D(array, buffer)
1844518522 integer(FP_SIZE), allocatable, intent(out) :: array(:)
@@ -18453,7 +18530,11 @@ pure subroutine FP_SIZE_COMM_EXPAND_1D(array, buffer)
1845318530 if (all(bnd /= FP_NOT_ALLOC)) then
1845418531 allocate(array(bnd(1):bnd(2)))
1845518532 ndoubles = FP_RCOMMS_PER_BITS(size(array, kind=FP_SIZE) * storage_size(array))
18533+ #if defined(__INTEL_COMPILER) || defined(__INTEL_LLVM_COMPILER)
18534+ array(:) = transfer(buffer(header+1:header+ndoubles), 0_FP_SIZE, size(array))
18535+ #else
1845618536 array = transfer(buffer(header+1:header+ndoubles), array)
18537+ #endif
1845718538 end if
1845818539 end subroutine FP_SIZE_COMM_EXPAND_1D
1845918540
0 commit comments