diff --git a/.circleci/config.yml b/.circleci/config.yml index 4eb4e4463086..465aec7d9215 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -16,7 +16,7 @@ parameters: # Anchors to prevent forgetting to update a version os_version: &os_version ubuntu24 -baselibs_version: &baselibs_version v7.29.0 +baselibs_version: &baselibs_version v7.31.0 bcs_version: &bcs_version v11.6.0 tag_build_arg_name: &tag_build_arg_name maplversion diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 865a7d3d7136..d4260d2ee421 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -38,7 +38,7 @@ jobs: name: Build and Test MAPL GNU runs-on: ubuntu-latest container: - image: gmao/ubuntu24-geos-env-mkl:v7.29.0-openmpi_5.0.5-gcc_14.2.0 + image: gmao/ubuntu24-geos-env-mkl:v7.31.0-openmpi_5.0.5-gcc_14.2.0 # Per https://github.com/actions/virtual-environments/issues/1445#issuecomment-713861495 # It seems like we might not need secrets on GitHub Actions which is good for forked # pull requests @@ -89,7 +89,7 @@ jobs: name: Build and Test MAPL Intel runs-on: ubuntu-latest container: - image: gmao/ubuntu24-geos-env:v7.29.0-intelmpi_2021.13-ifort_2021.13 + image: gmao/ubuntu24-geos-env:v7.31.0-intelmpi_2021.13-ifort_2021.13 # Per https://github.com/actions/virtual-environments/issues/1445#issuecomment-713861495 # It seems like we might not need secrets on GitHub Actions which is good for forked # pull requests diff --git a/Apps/MAPL_GridCompSpecs_ACG.py b/Apps/MAPL_GridCompSpecs_ACG.py index 13d113da3787..c35651e50eda 100755 --- a/Apps/MAPL_GridCompSpecs_ACG.py +++ b/Apps/MAPL_GridCompSpecs_ACG.py @@ -200,6 +200,7 @@ def get_mandatory_options(cls): 'VLOCATION': ('vlocation', VLOCATION_EMIT), 'VLOC': ('vlocation', VLOCATION_EMIT), # these are Options that are not output but used to write + 'ALIAS': ('alias', identity_emit, False, False), 'CONDITION': ('condition', identity_emit, False, False), 'COND': ('condition', identity_emit, False, False), 'ALLOC': ('alloc', identity_emit, False, False), @@ -463,6 +464,7 @@ def digest(specs, args): for spec in specs[category]: # spec from list dims = None ungridded = None + alias = None option_values = dict() # dict of option values for column in spec: # for spec emit value column_value = spec[column] @@ -480,6 +482,10 @@ def digest(specs, args): dims = option_value elif option == Option.UNGRIDDED: ungridded = option_value + elif option == Option.ALIAS: + alias = Option.ALIAS(column_value) + if alias: + option_values[Option.INTERNAL_NAME] = alias # MANDATORY for option in mandatory_options: if option not in option_values: diff --git a/CHANGELOG.md b/CHANGELOG.md index 19511ba3f262..7d41215b4a01 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,12 +13,35 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Add column for ACG (ALIAS) that set the pointer variable to a different name than the `short_name` +- Updated CI to use Baselibs 7.31.0 + - Updates to GFE v1.18.0 + ### Fixed ### Removed ### Deprecated +## [2.53.1] - 2025-01-29 + +### Fixed + +- Fixed bug with `MAPL_GetHorzijIndex` when not points are passed on a processor causing a deadlock + +## [2.53.0] - 2025-01-24 + +### Changed + +- Updated ExtData so that if files are missing in a sequence the last value will be perisisted if one has not chosen `exact` option +- Update `components.yaml` + - `ESMA_env` v4.34.1 + - Fix GEOSpyD module on GMAO Desktops + +### Fixed + +- Changes were made to add attributes to the subgrids (i.e. created by dividing the MPI subdomain into smaller subdomains equal to the number of OpenMP threads) such that the correct dimensions for the MPI subdomain could be retrieved from the subgrids where ever needed. + ## [2.52.0] - 2025-01-17 ### Added @@ -33,7 +56,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Updated ExtData so that if files are missing in a sequence the last value will be perisisted if one has not chosen `exact` option - Changed MAPL_ESMFRegridder to require the dstMaskValues to be added as grid attribute to use fixed masking, fixes UFS issue - Increased formatting width of time index in ExtData2G diagnostic print - Updated GitHub checkout action to use blobless clones diff --git a/CMakeLists.txt b/CMakeLists.txt index 83113960be62..727f3603eb11 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ endif () project ( MAPL - VERSION 2.52.0 + VERSION 2.53.1 LANGUAGES Fortran CXX C) # Note - CXX is required for ESMF # Set the possible values of build type for cmake-gui diff --git a/base/Base/Base_Base_implementation.F90 b/base/Base/Base_Base_implementation.F90 index b50e84e98897..41639a687dd9 100644 --- a/base/Base/Base_Base_implementation.F90 +++ b/base/Base/Base_Base_implementation.F90 @@ -1557,11 +1557,24 @@ module subroutine MAPL_GRID_INTERIOR(GRID,I1,IN,J1,JN) integer :: gridRank integer, allocatable :: localDeToDeMap(:) integer :: rc + logical :: isPresent + integer :: global_grid_info(10) i1=-1 j1=-1 in=-1 jn=-1 + + call ESMF_AttributeGet(grid, name="GLOBAL_GRID_INFO", isPresent=isPresent, _RC) + if (isPresent) then + call ESMF_AttributeGet(grid, name="GLOBAL_GRID_INFO", valueList=global_grid_info, _RC) + I1 = global_grid_info(7) + IN = global_grid_info(8) + j1 = global_grid_info(9) + JN = global_grid_info(10) + _RETURN(_SUCCESS) + end if + call ESMF_GridGet (GRID, dimCount=gridRank, distGrid=distGrid, _RC) call ESMF_DistGridGet(distGRID, delayout=layout, _RC) call ESMF_DELayoutGet(layout, deCount = nDEs, localDeCount=localDeCount,_RC) @@ -2138,6 +2151,24 @@ module subroutine MAPL_GridGetInterior(GRID,I1,IN,J1,JN) integer :: deId integer :: gridRank integer :: rc + logical :: isPresent + integer :: global_grid_info(10) + + i1=-1 + j1=-1 + in=-1 + jn=-1 + + call ESMF_AttributeGet(grid, name="GLOBAL_GRID_INFO", isPresent=isPresent, _RC) + if (isPresent) then + call ESMF_AttributeGet(grid, name="GLOBAL_GRID_INFO", valueList=global_grid_info, _RC) + I1 = global_grid_info(7) + IN = global_grid_info(8) + j1 = global_grid_info(9) + JN = global_grid_info(10) + _RETURN(_SUCCESS) + end if + call ESMF_GridGet (GRID, dimCount=gridRank, distGrid=distGrid, _RC) call ESMF_DistGridGet(distGRID, delayout=layout, _RC) @@ -2601,7 +2632,6 @@ module subroutine MAPL_GetHorzIJIndex(npts,II,JJ,lon,lat,lonR8,latR8,Grid, rc) type(ESMF_CoordSys_Flag) :: coordSys character(len=ESMF_MAXSTR) :: grid_type - _RETURN_IF(npts == 0 ) ! if the grid is present then we can just get the prestored edges and the dimensions of the grid ! this also means we are running on a distributed grid ! if grid not present then the we just be running outside of ESMF and the user must @@ -2627,9 +2657,7 @@ module subroutine MAPL_GetHorzIJIndex(npts,II,JJ,lon,lat,lonR8,latR8,Grid, rc) tmp_lats = latR8 end if -!AOO change tusing GridType atribute if (im_world*6==jm_world) then - call ESMF_AttributeGet(grid, name='GridType', value=grid_type, _RC) - if(trim(grid_type) == "Cubed-Sphere") then + if (im_world*6==jm_world) then call MAPL_GetGlobalHorzIJIndex(npts, II, JJ, lon=lon, lat=lat, lonR8=lonR8, latR8=latR8, Grid=Grid, _RC) @@ -2760,9 +2788,6 @@ module subroutine MAPL_GetGlobalHorzIJIndex(npts,II,JJ,lon,lat,lonR8,latR8,Grid, logical :: good_grid, stretched - ! Return if no local points - _RETURN_IF(npts == 0) - if ( .not. present(grid)) then _FAIL("need a cubed-sphere grid") endif @@ -2779,10 +2804,11 @@ module subroutine MAPL_GetGlobalHorzIJIndex(npts,II,JJ,lon,lat,lonR8,latR8,Grid, ! make sure the grid can be used in this subroutine good_grid = grid_is_ok(grid) - if ( .not. good_grid ) then _FAIL( "MAPL_GetGlobalHorzIJIndex cannot handle this grid") endif + ! Return if no local points + _RETURN_IF(npts==0) ! shift the grid away from Japan Fuji Mt. shift0 = shift @@ -2868,28 +2894,33 @@ function grid_is_ok(grid) result(OK) type(ESMF_Grid), intent(inout) :: grid logical :: OK integer :: I1, I2, J1, J2, j - real(ESMF_KIND_R8), pointer :: corner_lons(:,:), corner_lats(:,:) + real(ESMF_KIND_R8), allocatable :: corner_lons(:,:), corner_lats(:,:) real(ESMF_KIND_R8), allocatable :: lonRe(:), latRe(:) real(ESMF_KIND_R8), allocatable :: accurate_lat(:), accurate_lon(:) real(ESMF_KIND_R8) :: stretch_factor, target_lon, target_lat, shift0 real :: tolerance + integer :: local_dims(3) tolerance = epsilon(1.0) call MAPL_GridGetInterior(grid,I1,I2,J1,J2) + call MAPL_GridGet(grid, localCellCountPerDim=local_dims, _RC) OK = .true. ! check the edge of face 1 along longitude - call ESMF_GridGetCoord(grid,localDE=0,coordDim=1,staggerloc=ESMF_STAGGERLOC_CORNER, & - farrayPtr=corner_lons, rc=status) - call ESMF_GridGetCoord(grid,localDE=0,coordDim=2,staggerloc=ESMF_STAGGERLOC_CORNER, & - farrayPtr=corner_lats, rc=status) + !call ESMF_GridGetCoord(grid,localDE=0,coordDim=1,staggerloc=ESMF_STAGGERLOC_CORNER, & + ! farrayPtr=corner_lons, _RC) + !call ESMF_GridGetCoord(grid,localDE=0,coordDim=2,staggerloc=ESMF_STAGGERLOC_CORNER, & + ! farrayPtr=corner_lats, _RC) + allocate(corner_lons(local_dims(1)+1, local_dims(2)+1)) + allocate(corner_lats(local_dims(1)+1, local_dims(2)+1)) + call MAPL_GridGetCorners(grid, corner_lons, corner_lats, _RC) if ( I1 == 1 .and. J1 == 1 ) then - allocate(lonRe(j2-j1+1), latRe(j2-j1+1)) - call MAPL_Reverse_Schmidt(grid, stretched, J2-J1+1, lonR8=corner_lons(1,:), & - latR8=corner_lats(1,:), lonRe=lonRe, latRe=latRe, _RC) + allocate(lonRe(local_dims(2)), latRe(local_dims(2))) + call MAPL_Reverse_Schmidt(grid, stretched, local_dims(2), lonR8=corner_lons(1,1:local_dims(2)), & + latR8=corner_lats(1,1:local_dims(2)), lonRe=lonRe, latRe=latRe, _RC) - allocate(accurate_lon(j2-j1+1), accurate_lat(j2-j1+1)) + allocate(accurate_lon(local_dims(2)), accurate_lat(local_dims(2))) shift0 = shift if (stretched) shift0 = 0 diff --git a/base/MaplGrid.F90 b/base/MaplGrid.F90 index fdac6371357e..153fdd11d865 100644 --- a/base/MaplGrid.F90 +++ b/base/MaplGrid.F90 @@ -265,10 +265,19 @@ subroutine MAPL_GridGet(GRID, globalCellCountPerDim, localCellCountPerDim, layou type(ESMF_DistGrid) :: distGrid integer, allocatable :: maxindex(:,:),minindex(:,:) integer, pointer :: ims(:),jms(:) + integer :: global_grid_info(10) pglobal = present(globalCellCountPerDim) plocal = present(localCellCountPerDim) + call ESMF_AttributeGet(grid, name="GLOBAL_GRID_INFO", isPresent=isPresent, _RC) + if (isPresent) then + call ESMF_AttributeGet(grid, name="GLOBAL_GRID_INFO", valueList=global_grid_info, _RC) + if (pglobal) globalCellCountPerDim = global_grid_info(1:3) + if (plocal) localCellCountPerDim = global_grid_info(4:6) + _RETURN(_SUCCESS) + end if + if (pglobal .or. plocal) then call ESMF_GridGet(grid, dimCount=gridRank, _RC) diff --git a/components.yaml b/components.yaml index bedab2379e88..27bfcc960af7 100644 --- a/components.yaml +++ b/components.yaml @@ -5,7 +5,7 @@ MAPL: ESMA_env: local: ./ESMA_env remote: ../ESMA_env.git - tag: v4.34.0 + tag: v4.34.1 develop: main ESMA_cmake: diff --git a/generic/OpenMP_Support.F90 b/generic/OpenMP_Support.F90 index 9cdf0a3ac1c8..9a9c33b629b1 100644 --- a/generic/OpenMP_Support.F90 +++ b/generic/OpenMP_Support.F90 @@ -6,6 +6,7 @@ module MAPL_OpenMP_Support use MAPL_maplgrid use MAPL_ExceptionHandling use mapl_KeywordEnforcerMod + use MAPL_BaseMod, only : MAPL_Grid_Interior !$ use omp_lib implicit none @@ -83,7 +84,7 @@ function make_subgrids_from_bounds(primary_grid, bounds, unusable, rc) result(su type(Interval), intent(in) :: bounds(:) class(KeywordEnforcer), optional, intent(in) :: unusable integer, optional, intent(out) :: rc - integer :: local_count(3) + integer :: local_count(3), global_count(3) integer :: status integer :: petMap(1,1,1) integer :: myPet, section, i, j, k, count, size_ @@ -102,7 +103,7 @@ function make_subgrids_from_bounds(primary_grid, bounds, unusable, rc) result(su !end do allocate(subgrids(size(bounds))) - call MAPL_GridGet(primary_grid,localcellcountPerDim=local_count, _RC) + call MAPL_GridGet(primary_grid,localcellcountPerDim=local_count, globalCellCountPerDim=global_count, _RC) call ESMF_VMGetCurrent(vm, _RC) call ESMF_VMGet(vm, localPET=myPET, _RC) @@ -175,6 +176,22 @@ function make_subgrids_from_bounds(primary_grid, bounds, unusable, rc) result(su itemCount = count, valueList=lons1d, _RC) call ESMF_AttributeSet(subgrids(i), name='GridCornerLats:', & itemCount = count, valueList=lats1d, _RC) + block + integer :: global_grid_info(10) + integer :: i1,i2,j1,j2 + call MAPL_Grid_Interior(primary_grid,i1,i2,j1,j2) + global_grid_info(1:3) = global_count + !global_grid_info(4:6) = local_count + global_grid_info(4) = size(new_lons,1) + global_grid_info(5) = size(new_lons,2) + global_grid_info(6) = local_count(3) + global_grid_info(7) = i1 + global_grid_info(8) = i2 + global_grid_info(9) = j1 + bounds(i)%min - 1 + global_grid_info(10) = j1 + bounds(i)%max - 1 + call ESMF_AttributeSet(subgrids(i), name="GLOBAL_GRID_INFO", & + itemCount=10, valueList=global_grid_info, _RC) + end block deallocate(lons1d, lats1d) deallocate(new_corner_lons, new_corner_lats) diff --git a/gridcomps/ExtData2G/ExtDataBracket.F90 b/gridcomps/ExtData2G/ExtDataBracket.F90 index 9fff7624bbb3..8c8c84da4f7f 100644 --- a/gridcomps/ExtData2G/ExtDataBracket.F90 +++ b/gridcomps/ExtData2G/ExtDataBracket.F90 @@ -188,8 +188,6 @@ subroutine interpolate_to_time(this,field,time,rc) right_node_set = this%right_node%check_if_initialized(_RC) left_node_set = this%left_node%check_if_initialized(_RC) - call ESMF_TimePrint(this%left_node%time,options='string',preString='left bracket time: ') - call ESMF_TimePrint(this%right_node%time,options='string',preString='right bracket time: ') alpha = 0.0 if ( (.not.this%disable_interpolation) .and. (.not.this%intermittent_disable) .and. right_node_set .and. left_node_set) then