diff --git a/src/clib/pio.h b/src/clib/pio.h index f6b2780f4..7e0b59613 100644 --- a/src/clib/pio.h +++ b/src/clib/pio.h @@ -317,6 +317,11 @@ typedef struct io_desc_t * everywhere (false) */ bool needsfill; + /** If true, skip the needsfill coverage check and force + * needsfill=false. Set via PIOc_InitDecomp_flags / + * PIOc_InitDecomp_bc_flags (or Fortran force_nofill). */ + bool force_nofill; + /** If the map is not monotonically increasing we will need to * sort it. */ bool needssort; @@ -823,10 +828,19 @@ extern "C" { const PIO_Offset *compmap, int *ioidp, const int *rearr, const PIO_Offset *iostart, const PIO_Offset *iocount); int PIOc_InitDecomp(int iosysid, int pio_type, int ndims, const int *gdimlen, int maplen, - const PIO_Offset *compmap, int *ioidp, const int *rearr, - const PIO_Offset *iostart, const PIO_Offset *iocount); + const PIO_Offset *compmap, int *ioidp, const int *rearr, + const PIO_Offset *iostart, const PIO_Offset *iocount); + /** Like PIOc_InitDecomp, but force_nofill!=0 skips the needsfill check. */ + int PIOc_InitDecomp_flags(int iosysid, int pio_type, int ndims, const int *gdimlen, int maplen, + const PIO_Offset *compmap, int *ioidp, const int *rearr, + const PIO_Offset *iostart, const PIO_Offset *iocount, + int force_nofill); int PIOc_InitDecomp_bc(int iosysid, int basetype, int ndims, const int *gdimlen, - const long int *start, const long int *count, int *ioidp); + const long int *start, const long int *count, int *ioidp); + /** Like PIOc_InitDecomp_bc, but force_nofill!=0 skips the needsfill check. */ + int PIOc_InitDecomp_bc_flags(int iosysid, int basetype, int ndims, const int *gdimlen, + const long int *start, const long int *count, int *ioidp, + int force_nofill); /* Init decomposition with 0-based compmap array. */ int PIOc_init_decomp(int iosysid, int pio_type, int ndims, const int *gdimlen, int maplen, diff --git a/src/clib/pio_rearrange.c b/src/clib/pio_rearrange.c index 74627f646..bc7026e6c 100644 --- a/src/clib/pio_rearrange.c +++ b/src/clib/pio_rearrange.c @@ -1141,6 +1141,14 @@ determine_fill(iosystem_desc_t *ios, io_desc_t *iodesc, const int *gdimlen, pioassert(ios && iodesc && gdimlen && compmap, "invalid input", __FILE__, __LINE__); + /* Application requested skip of the coverage / hole-fill path. */ + if (iodesc->force_nofill) + { + iodesc->needsfill = false; + PLOG((2, "determine_fill: force_nofill set, needsfill forced false")); + return PIO_NOERR; + } + /* Determine size of data space. */ for (int i = 0; i < iodesc->ndims; i++) totalgridsize *= gdimlen[i]; @@ -1165,9 +1173,6 @@ determine_fill(iosystem_desc_t *ios, io_desc_t *iodesc, const int *gdimlen, * total data size then we need fill values. */ iodesc->needsfill = totalllen < totalgridsize; - /* TURN OFF FILL for timing test - iodesc->needsfill=false; */ - return PIO_NOERR; } diff --git a/src/clib/pioc.c b/src/clib/pioc.c index 1be592345..f7f141af1 100644 --- a/src/clib/pioc.c +++ b/src/clib/pioc.c @@ -500,14 +500,32 @@ int PIOc_InitDecomp(int iosysid, int pio_type, int ndims, const int *gdimlen, int maplen, const PIO_Offset *compmap, int *ioidp, const int *rearranger, const PIO_Offset *iostart, const PIO_Offset *iocount) +{ + return PIOc_InitDecomp_flags(iosysid, pio_type, ndims, gdimlen, maplen, compmap, + ioidp, rearranger, iostart, iocount, 0); +} + +/** + * Same as PIOc_InitDecomp(), with optional force_nofill. + * + * If force_nofill is non-zero, skip the needsfill coverage check and + * force needsfill=false for this decomposition. + * + * @param force_nofill non-zero to skip needsfill check + */ +int +PIOc_InitDecomp_flags(int iosysid, int pio_type, int ndims, const int *gdimlen, int maplen, + const PIO_Offset *compmap, int *ioidp, const int *rearranger, + const PIO_Offset *iostart, const PIO_Offset *iocount, + int force_nofill) { iosystem_desc_t *ios; /* Pointer to io system information. */ io_desc_t *iodesc; /* The IO description. */ int mpierr = MPI_SUCCESS, mpierr2; /* Return code from MPI function calls. */ int ierr; /* Return code. */ - PLOG((1, "PIOc_InitDecomp iosysid = %d pio_type = %d ndims = %d maplen = %d", - iosysid, pio_type, ndims, maplen)); + PLOG((1, "PIOc_InitDecomp_flags iosysid = %d pio_type = %d ndims = %d maplen = %d force_nofill = %d", + iosysid, pio_type, ndims, maplen, force_nofill)); #ifdef USE_MPE pio_start_mpe_log(DECOMP); @@ -566,8 +584,10 @@ PIOc_InitDecomp(int iosysid, int pio_type, int ndims, const int *gdimlen, int ma mpierr = MPI_Bcast(&iocount_present, 1, MPI_CHAR, ios->compmain, ios->intercomm); if (iocount_present && !mpierr) mpierr = MPI_Bcast((PIO_Offset *)iocount, ndims, MPI_OFFSET, ios->compmain, ios->intercomm); - PLOG((2, "PIOc_InitDecomp iosysid = %d pio_type = %d ndims = %d maplen = %d rearranger_present = %d iostart_present = %d " - "iocount_present = %d ", iosysid, pio_type, ndims, maplen, rearranger_present, iostart_present, iocount_present)); + if (!mpierr) + mpierr = MPI_Bcast(&force_nofill, 1, MPI_INT, ios->compmain, ios->intercomm); + PLOG((2, "PIOc_InitDecomp_flags iosysid = %d pio_type = %d ndims = %d maplen = %d rearranger_present = %d iostart_present = %d " + "iocount_present = %d force_nofill = %d", iosysid, pio_type, ndims, maplen, rearranger_present, iostart_present, iocount_present, force_nofill)); } /* Handle MPI errors. */ @@ -588,6 +608,9 @@ PIOc_InitDecomp(int iosysid, int pio_type, int ndims, const int *gdimlen, int ma if ((ierr = malloc_iodesc(ios, pio_type, ndims, &iodesc))) return pio_err(ios, NULL, ierr, __FILE__, __LINE__); + /* Optional: skip needsfill coverage check for this decomp. */ + iodesc->force_nofill = (force_nofill != 0); + /* Remember the maplen. */ iodesc->maplen = maplen; @@ -648,7 +671,7 @@ PIOc_InitDecomp(int iosysid, int pio_type, int ndims, const int *gdimlen, int ma iodesc->rearranger = ios->default_rearranger; else iodesc->rearranger = *rearranger; - PLOG((2, "iodesc->rearranger = %d", iodesc->rearranger)); + PLOG((2, "iodesc->rearranger = %d force_nofill = %d", iodesc->rearranger, iodesc->force_nofill)); /* Is this the subset rearranger? */ if (iodesc->rearranger == PIO_REARR_SUBSET) @@ -1166,14 +1189,31 @@ PIOc_init_decomp(int iosysid, int pio_type, int ndims, const int *gdimlen, int m int PIOc_InitDecomp_bc(int iosysid, int pio_type, int ndims, const int *gdimlen, const long int *start, const long int *count, int *ioidp) +{ + return PIOc_InitDecomp_bc_flags(iosysid, pio_type, ndims, gdimlen, start, count, + ioidp, 0); +} +/** + * Same as PIOc_InitDecomp_bc(), with optional force_nofill. + * + * If force_nofill is non-zero, skip the needsfill coverage check and + * force needsfill=false for this decomposition. + * + * @param force_nofill non-zero to skip needsfill check + */ +int +PIOc_InitDecomp_bc_flags(int iosysid, int pio_type, int ndims, const int *gdimlen, + const long int *start, const long int *count, int *ioidp, + int force_nofill) { iosystem_desc_t *ios; int n, i, maplen = 1; PIO_Offset prod[ndims], loc[ndims]; int rearr = PIO_REARR_SUBSET; - PLOG((1, "PIOc_InitDecomp_bc iosysid = %d pio_type = %d ndims = %d")); + PLOG((1, "PIOc_InitDecomp_bc_flags iosysid = %d pio_type = %d ndims = %d force_nofill = %d", + iosysid, pio_type, ndims, force_nofill)); /* Get the info about the io system. */ if (!(ios = pio_get_iosystem_from_id(iosysid))) @@ -1219,8 +1259,8 @@ PIOc_InitDecomp_bc(int iosysid, int pio_type, int ndims, const int *gdimlen, } } - return PIOc_InitDecomp(iosysid, pio_type, ndims, gdimlen, maplen, compmap, ioidp, - &rearr, NULL, NULL); + return PIOc_InitDecomp_flags(iosysid, pio_type, ndims, gdimlen, maplen, compmap, ioidp, + &rearr, NULL, NULL, force_nofill); } /** diff --git a/src/flib/piolib_mod.F90 b/src/flib/piolib_mod.F90 index 285de5475..4b21f1c83 100644 --- a/src/flib/piolib_mod.F90 +++ b/src/flib/piolib_mod.F90 @@ -529,19 +529,23 @@ end subroutine seterrorhandlingiosysid !! @param compcount The count for the block-cyclic computational !! decomposition !! @param iodesc @copydoc iodesc_generate + !! @param force_nofill Optional. If present and .true., skip the + !! needsfill coverage check and force needsfill=false. !! @author Jim Edwards !< - subroutine PIO_initdecomp_bc(iosystem,basepiotype,dims,compstart,compcount,iodesc) + subroutine PIO_initdecomp_bc(iosystem,basepiotype,dims,compstart,compcount,iodesc,force_nofill) type (iosystem_desc_t), intent(inout) :: iosystem integer(i4), intent(in) :: basepiotype integer(i4), intent(in) :: dims(:) integer (kind=PIO_OFFSET_KIND) :: compstart(:) integer (kind=PIO_OFFSET_KIND) :: compcount(:) type (IO_desc_t), intent(out) :: iodesc + logical, optional, intent(in) :: force_nofill interface - integer(C_INT) function PIOc_InitDecomp_bc(iosysid, basetype, ndims, dims, compstart, compcount, ioidp) & - bind(C,name="PIOc_InitDecomp_bc") + integer(C_INT) function PIOc_InitDecomp_bc_flags(iosysid, basetype, ndims, dims, & + compstart, compcount, ioidp, force_nofill) & + bind(C,name="PIOc_InitDecomp_bc_flags") use iso_c_binding integer(C_INT), value :: iosysid integer(C_INT), value :: basetype @@ -550,12 +554,14 @@ integer(C_INT) function PIOc_InitDecomp_bc(iosysid, basetype, ndims, dims, comps integer(C_INT) :: ioidp integer(C_SIZE_T) :: compstart(*) integer(C_SIZE_T) :: compcount(*) - end function PIOc_InitDecomp_bc + integer(C_INT), value :: force_nofill + end function PIOc_InitDecomp_bc_flags end interface integer :: i, ndims integer, allocatable :: cdims(:) integer(PIO_Offset_kind), allocatable :: cstart(:), ccount(:) integer :: ierr + integer(C_INT) :: c_force_nofill ndims = size(dims) @@ -567,8 +573,13 @@ end function PIOc_InitDecomp_bc ccount(i) = compcount(ndims-i+1) end do - ierr = PIOc_InitDecomp_bc(iosystem%iosysid, basepiotype, ndims, cdims, & - cstart, ccount, iodesc%ioid) + c_force_nofill = 0 + if (present(force_nofill)) then + if (force_nofill) c_force_nofill = 1 + end if + + ierr = PIOc_InitDecomp_bc_flags(iosystem%iosysid, basepiotype, ndims, cdims, & + cstart, ccount, iodesc%ioid, c_force_nofill) deallocate(cstart, ccount, cdims) @@ -831,7 +842,7 @@ end subroutine initdecomp_1dof_nf_i8 !! @param iocount The count for the block-cyclic io decomposition !! @author Jim Edwards !< - subroutine PIO_initdecomp_dof_i4(iosystem, basepiotype, dims, compdof, iodesc, rearr, iostart, iocount) + subroutine PIO_initdecomp_dof_i4(iosystem, basepiotype, dims, compdof, iodesc, rearr, iostart, iocount, force_nofill) type (iosystem_desc_t), intent(inout) :: iosystem integer(i4), intent(in) :: basepiotype integer(i4), intent(in) :: compdof(:) ! global degrees of freedom for computational decomposition @@ -840,21 +851,23 @@ subroutine PIO_initdecomp_dof_i4(iosystem, basepiotype, dims, compdof, iodesc, r type (io_desc_t), intent(inout) :: iodesc integer(PIO_OFFSET_KIND), pointer :: internal_compdof(:) integer(i4), intent(in) :: dims(:) + logical, optional, intent(in) :: force_nofill allocate(internal_compdof(size(compdof))) internal_compdof = int(compdof,PIO_OFFSET_KIND) if(present(iostart) .and. present(iocount) ) then call pio_initdecomp_dof_i8(iosystem, basepiotype, dims, internal_compdof, iodesc, & - PIO_REARR_SUBSET, iostart, iocount) + PIO_REARR_SUBSET, iostart, iocount, force_nofill=force_nofill) else - call pio_initdecomp_dof_i8(iosystem, basepiotype, dims, internal_compdof, iodesc, rearr) + call pio_initdecomp_dof_i8(iosystem, basepiotype, dims, internal_compdof, iodesc, rearr, & + force_nofill=force_nofill) endif deallocate(internal_compdof) end subroutine PIO_initdecomp_dof_i4 - subroutine PIO_initdecomp_internal(iosystem,basepiotype,dims,maplen, compdof, iodesc, rearr, iostart, iocount) + subroutine PIO_initdecomp_internal(iosystem,basepiotype,dims,maplen, compdof, iodesc, rearr, iostart, iocount, force_nofill) type (iosystem_desc_t), intent(in) :: iosystem integer(i4), intent(in) :: basepiotype integer(i4), intent(in) :: dims(:) @@ -863,16 +876,18 @@ subroutine PIO_initdecomp_internal(iosystem,basepiotype,dims,maplen, compdof, io integer, optional, target :: rearr integer (PIO_OFFSET_KIND), optional :: iostart(:), iocount(:) type (io_desc_t), intent(inout) :: iodesc + logical, optional, intent(in) :: force_nofill integer(c_int) :: ndims integer(c_int), dimension(:), allocatable, target :: cdims integer(PIO_OFFSET_KIND), dimension(:), allocatable, target :: cstart, ccount + integer(C_INT) :: c_force_nofill type(C_PTR) :: crearr interface - integer(C_INT) function PIOc_InitDecomp(iosysid,basetype,ndims,dims, & - maplen, compmap, ioidp, rearr, iostart, iocount) & - bind(C,name="PIOc_InitDecomp") + integer(C_INT) function PIOc_InitDecomp_flags(iosysid,basetype,ndims,dims, & + maplen, compmap, ioidp, rearr, iostart, iocount, force_nofill) & + bind(C,name="PIOc_InitDecomp_flags") use iso_c_binding integer(C_INT), value :: iosysid integer(C_INT), value :: basetype @@ -884,7 +899,8 @@ integer(C_INT) function PIOc_InitDecomp(iosysid,basetype,ndims,dims, & type(C_PTR), value :: rearr type(C_PTR), value :: iostart type(C_PTR), value :: iocount - end function PIOc_InitDecomp + integer(C_INT), value :: force_nofill + end function PIOc_InitDecomp_flags end interface integer :: ierr,i @@ -900,6 +916,11 @@ end function PIOc_InitDecomp crearr = C_NULL_PTR endif + c_force_nofill = 0 + if (present(force_nofill)) then + if (force_nofill) c_force_nofill = 1 + end if + if(present(iostart) .and. present(iocount)) then allocate(cstart(ndims), ccount(ndims)) do i=1,ndims @@ -907,12 +928,12 @@ end function PIOc_InitDecomp ccount(i) = iocount(ndims-i+1) end do - ierr = PIOc_InitDecomp(iosystem%iosysid, basepiotype, ndims, cdims, & - maplen, compdof, iodesc%ioid, crearr, C_LOC(cstart), C_LOC(ccount)) + ierr = PIOc_InitDecomp_flags(iosystem%iosysid, basepiotype, ndims, cdims, & + maplen, compdof, iodesc%ioid, crearr, C_LOC(cstart), C_LOC(ccount), c_force_nofill) deallocate(cstart, ccount) else - ierr = PIOc_InitDecomp(iosystem%iosysid, basepiotype, ndims, cdims, & - maplen, compdof, iodesc%ioid, crearr, C_NULL_PTR, C_NULL_PTR) + ierr = PIOc_InitDecomp_flags(iosystem%iosysid, basepiotype, ndims, cdims, & + maplen, compdof, iodesc%ioid, crearr, C_NULL_PTR, C_NULL_PTR, c_force_nofill) end if deallocate(cdims) @@ -1021,7 +1042,7 @@ end subroutine PIO_initdecomp_readonly !! I8 version of PIO_initdecomp_dof_i4. !! @author Jim Edwards subroutine PIO_initdecomp_dof_i8(iosystem, basepiotype, dims, compdof, & - iodesc, rearr, iostart, iocount) + iodesc, rearr, iostart, iocount, force_nofill) type (iosystem_desc_t), intent(in) :: iosystem integer(i4), intent(in) :: basepiotype integer(i4), intent(in) :: dims(:) @@ -1029,6 +1050,7 @@ subroutine PIO_initdecomp_dof_i8(iosystem, basepiotype, dims, compdof, & integer, optional, target :: rearr integer (PIO_OFFSET_KIND), optional :: iostart(:), iocount(:) type (io_desc_t), intent(inout) :: iodesc + logical, optional, intent(in) :: force_nofill integer :: maplen #ifdef TIMING @@ -1038,7 +1060,7 @@ subroutine PIO_initdecomp_dof_i8(iosystem, basepiotype, dims, compdof, & maplen = size(compdof) call PIO_initdecomp_internal(iosystem, basepiotype, dims, maplen, & - compdof, iodesc, rearr, iostart, iocount) + compdof, iodesc, rearr, iostart, iocount, force_nofill) #ifdef TIMING call t_stopf("PIO:initdecomp_dof")