Skip to content

Generalized Indices: MPP_REDISTRIBUTE#1886

Open
abrooks1085 wants to merge 3 commits into
NOAA-GFDL:mainfrom
abrooks1085:feature/general-indices-redistribute
Open

Generalized Indices: MPP_REDISTRIBUTE#1886
abrooks1085 wants to merge 3 commits into
NOAA-GFDL:mainfrom
abrooks1085:feature/general-indices-redistribute

Conversation

@abrooks1085

@abrooks1085 abrooks1085 commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Description
This PR adds generalized storage-layout support to MPP_REDISTRIBUTE for 2D–5D fields. The main change is to allow callers to pass an optional axis_to_dim mapping so arrays whose logical (x,y,z) axes are stored in a different physical dimension order can be redistributed correctly. The PR modifies mpp_do_redistribute.fh, mpp_update_domains2D.fh, and adds a regression path in test_mpp_domains.F90 / test_mpp_domains2.sh.

  • Adds an optional axis_to_dim_in(3) argument through the MPP_REDISTRIBUTE_*D_ interfaces.
  • Defines axis_to_dim(logical_axis) = storage_dimension, so for example (/3,1,2/) means:
    • logical x is stored in dimension 3
    • logical y is stored in dimension 1
    • logical z is stored in dimension 2

How Has This Been Tested?
amdbox + intel

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • Any dependent changes have been merged and published in downstream modules
  • New check tests, if applicable, are included
  • make distcheck passes

@uramirez8707 uramirez8707 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just minor comments regarding the new argument name. Looks good to me otherwise.

Comment on lines +84 to +86
jo = j - js + 1
do i = is,ie
io = i - is + 1

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These io and jo variables appear never be used?

logical, intent(in), optional :: complete, free
integer, intent(in), optional :: list_size
integer, intent(in), optional :: position
integer, intent(in), optional :: axis_to_dim_in(3)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please document this new arguments.

Can we make it consistent with the other subroutines? I think we used dim_order.

logical, intent(in), optional :: complete, free
integer, intent(in), optional :: list_size
integer, intent(in), optional :: position
integer, intent(in), optional :: axis_to_dim_in(3)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this be 2? axis_to_dim_in(2)

integer, intent(in), optional :: position
integer, intent(in), optional :: axis_to_dim_in(3)
MPP_TYPE_ :: field3D_in (size(field_in, 1),size(field_in, 2),size(field_in ,3)*size(field_in ,4))
MPP_TYPE_ :: field3D_out(size(field_out,1),size(field_out,2),size(field_out,3)*size(field_out,4))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless I'm misunderstanding something, it seems to me that this approach of fusing the third and fourth dimensions should only work with (i,j,*,*) or (j,i,*,*) dimension orders. Are these the only cases that we need to support?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I think you are right to question the logical equivalence here.

I was initially focused on preserving the storage layout: fusing storage dimensions 3 and 4 into a rank-3 view preserves Fortran column-major ordering and avoids a repack or transpose. However, looking more carefully at MPP_DO_REDISTRIBUTE_3D_, the routine redistributes logical x/y rectangles and carries the full logical z extent along with each communicated region. The part I missed is the fourth dimension may be fused with an intended decomposed horizontal axis.

I'm going to instead treat the fourth dimension as a list of independent 3D views, one for each field(:,:,:,l) slice. That is, I'll pass a 1D list of base addresses/pointers, where each entry points to the start of one contiguous 3D slice of the original 4D field. Each 3D slice can then be passed through the existing 3D redistribution path using axis_to_dim without copying.

This will preserves the intended logical behavior: x/y determine the communicated domain region, while the full logical z extent and each fourth-dimension slice are carried along.

I can also limit the performance impact, by making packing/unpacking loops oriented towards storage layout instead of logical layout like I have here. Using axis_to_dim, compute the logical bounds for x/y/z, map them onto storage dimensions, and traverse each 3D view in column-major storage order. That keeps the innermost loop unit-stride where possible while still preserving the logical decomposition.

Thanks again for pointing this out.

MPP_TYPE_ :: field3D_in (size(field_in, 1),size(field_in, 2), &
& size(field_in ,3)*size(field_in,4)*size(field_in ,5))
MPP_TYPE_ :: field3D_out(size(field_out,1),size(field_out,2), &
& size(field_out,3)*size(field_out,4)*size(field_out,5))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above. Unless I'm misunderstanding, it seems to me that this should only work with (i,j,*,*,*) or (j,i,*,*,*) dimension orders.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants