Skip to content

Commit 981ffec

Browse files
committed
Stop using file striping size to automatically set header extent
Automatically set the size of file header extent using the file striping size obtained from MPI-IO hint striping_unit may yield an unexpectedly large file header extent and cause movement of data sections if new metadata is added when the program re-enter the define mode. With this commit, file striping size will no longer be used to set the file header alignment size. However, users can still set nc_header_align_size in PNETCDF_HINTS environment variable or v_align in ncmpi__enddef() to customize the size of header extent.
1 parent 5b4b644 commit 981ffec

File tree

1 file changed

+60
-71
lines changed

1 file changed

+60
-71
lines changed

src/drivers/ncmpio/ncmpio_enddef.c

Lines changed: 60 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -311,10 +311,8 @@ NC_begins(NC *ncp)
311311
if (ncp->format == 1 && end_var > X_OFF_MAX)
312312
DEBUG_RETURN_ERROR(NC_EVARSIZE)
313313

314-
/* this will pad out non-record variables with zero to the
315-
* requested alignment. record variables are a bit trickier.
316-
* we don't do anything special with them */
317-
ncp->vars.value[i]->begin = D_RNDUP(end_var, ncp->fx_v_align);
314+
/* this will pad out non-record variables with the 4-byte alignment */
315+
ncp->vars.value[i]->begin = D_RNDUP(end_var, 4);
318316

319317
if (ncp->old != NULL) {
320318
/* move to the next fixed variable */
@@ -336,19 +334,14 @@ NC_begins(NC *ncp)
336334

337335
/* end_var now is pointing to the end of last non-record variable */
338336

339-
/* only (re)calculate begin_rec if there is not sufficient
340-
* space at end of non-record variables or if start of record
341-
* variables is not aligned as requested by ncp->r_align.
342-
* If the existing begin_rec is already >= index, then leave the
343-
* begin_rec as is (in case some non-record variables are deleted)
337+
/* only (re)calculate begin_rec if there is no sufficient space at end of
338+
* non-record variables or if the start of record variables is not aligned
339+
* as requested by ncp->r_align.
344340
*/
345-
if (ncp->begin_rec < end_var ||
346-
ncp->begin_rec != D_RNDUP(ncp->begin_rec, ncp->fx_v_align))
347-
ncp->begin_rec = D_RNDUP(end_var, ncp->fx_v_align);
348-
349-
/* expand free space for fixed variable section */
350341
if (ncp->begin_rec < end_var + ncp->v_minfree)
351-
ncp->begin_rec = D_RNDUP(end_var + ncp->v_minfree, ncp->fx_v_align);
342+
ncp->begin_rec = end_var + ncp->v_minfree;
343+
344+
ncp->begin_rec = D_RNDUP(ncp->begin_rec, 4);
352345

353346
/* align the starting offset for record variable section */
354347
if (ncp->r_align > 1)
@@ -921,11 +914,13 @@ ncmpio_NC_check_voffs(NC *ncp)
921914

922915
/*----< ncmpio__enddef() >---------------------------------------------------*/
923916
/* This is a collective subroutine.
924-
* h_minfree Sets the pad at the end of the "header" section.
917+
* h_minfree Sets the pad at the end of the "header" section, i.e. at least
918+
* this amount of free space includes at the end of header extent.
925919
* v_align Controls the alignment of the beginning of the data section for
926920
* fixed size variables.
927921
* v_minfree Sets the pad at the end of the data section for fixed size
928-
* variables.
922+
* variables, i.e. at least this amount of free space between the
923+
* fixed-size variable section and record variable section.
929924
* r_align Controls the alignment of the beginning of the data section for
930925
* variables which have an unlimited dimension (record variables).
931926
*/
@@ -936,89 +931,83 @@ ncmpio__enddef(void *ncdp,
936931
MPI_Offset v_minfree,
937932
MPI_Offset r_align)
938933
{
939-
int i, flag, striping_unit, mpireturn, err=NC_NOERR, status=NC_NOERR;
934+
int i, num_fix_vars, mpireturn, err=NC_NOERR, status=NC_NOERR;
940935
char value[MPI_MAX_INFO_VAL];
941-
MPI_Offset all_fix_var_size;
942936
NC *ncp = (NC*)ncdp;
943937

938+
/* negative values of h_minfree, v_align, v_minfree, r_align have been
939+
* checked at dispatchers.
940+
*/
941+
944942
/* sanity check for NC_ENOTINDEFINE, NC_EINVAL, NC_EMULTIDEFINE_FNC_ARGS
945943
* has been done at dispatchers */
946944
ncp->h_minfree = h_minfree;
947945
ncp->v_minfree = v_minfree;
948946

949-
/* calculate a good align size for PnetCDF level hints:
950-
* header_align_size and var_align_size based on the MPI-IO hint
951-
* striping_unit. This hint can be either supplied by the user or obtained
952-
* from MPI-IO (for example, ROMIO's Lustre driver makes a system call to
953-
* get the striping parameters of a file).
947+
/* calculate a good file extent alignment size based on:
948+
* + hints set by users in the environment variable PNETCDF_HINTS
949+
* nc_header_align_size and nc_var_align_size
950+
* + v_align set in the call to ncmpi__enddef()
951+
* Hints set in the environment variable PNETCDF_HINTS have the higher
952+
* precedence than the ones set in the API calls.
953+
* The precedence of hints and arguments:
954+
* 1. hints set in PNETCDF_HINTS environment variable at run time
955+
* 2. hints set in the source codes, for example, a call to
956+
* MPI_Info_set("nc_header_align_size", "1048576");
957+
* 3. source codes calling ncmpi__enddef(). For example,
958+
* MPI_Offset v_align = 1048576;
959+
* ncmpi__enddef(ncid, 0, v_align, 0, 0);
960+
* 4. defaults
961+
* 0 for h_minfree
962+
* 512 for v_align
963+
* 0 for v_minfree
964+
* 4 for r_align
954965
*/
955-
MPI_Info_get(ncp->mpiinfo, "striping_unit", MPI_MAX_INFO_VAL-1, value,
956-
&flag);
957-
striping_unit = 0;
958-
if (flag) {
959-
errno = 0;
960-
striping_unit = (int)strtol(value,NULL,10);
961-
if (errno != 0) striping_unit = 0;
962-
}
963-
ncp->striping_unit = striping_unit;
964-
965-
all_fix_var_size = 0; /* sum of all defined fixed-size variables */
966-
for (i=0; i<ncp->vars.ndefined; i++) {
967-
if (IS_RECVAR(ncp->vars.value[i])) continue;
968-
all_fix_var_size += ncp->vars.value[i]->len;
969-
}
970966

971967
/* ncp->h_align, ncp->v_align, ncp->r_align, and ncp->chunk have been
972968
* set during file create/open */
973969

974-
if (ncp->h_align == 0) { /* user info does not set nc_header_align_size */
975-
if (v_align > 0)
970+
num_fix_vars = ncp->vars.ndefined - ncp->vars.num_rec_vars;
971+
972+
if (ncp->h_align == 0) { /* hint nc_header_align_size is not set */
973+
if (ncp->v_align > 0) /* hint nc_var_align_size is set */
974+
ncp->h_align = ncp->v_align;
975+
else if (v_align > 0) /* v_align is passed from ncmpi__enddef */
976976
ncp->h_align = v_align;
977-
else if (all_fix_var_size > 0 && r_align > 0) /* no fixed-size variable */
978-
ncp->h_align = r_align;
979-
else if (striping_unit &&
980-
all_fix_var_size > FILE_ALIGNMENT_LB * striping_unit)
981-
/* if striping_unit is available and file size sufficiently large */
982-
ncp->h_align = striping_unit;
983-
else
977+
978+
/* if no fixed-size variables is defined, use r_align */
979+
if (ncp->h_align == 0 && num_fix_vars == 0) {
980+
if (ncp->r_align > 0) /* hint nc_record_align_size is set */
981+
ncp->h_align = ncp->r_align;
982+
else if (r_align > 0) /* r_align is passed from ncmpi__enddef */
983+
ncp->h_align = r_align;
984+
}
985+
if (ncp->h_align == 0) /* still not set */
984986
ncp->h_align = FILE_ALIGNMENT_DEFAULT;
985987
}
986988
/* else respect user hint */
987989

988990
if (ncp->v_align == 0) { /* user info does not set nc_var_align_size */
989-
if (v_align > 0) /* else respect user hint */
991+
if (v_align > 0) /* v_align is passed from ncmpi__enddef */
990992
ncp->v_align = v_align;
991-
#ifdef USE_AGGRESSIVE_ALIGN
992-
else if (striping_unit &&
993-
all_fix_var_size > FILE_ALIGNMENT_LB * striping_unit)
994-
/* if striping_unit is available and file size sufficiently large */
995-
ncp->v_align = striping_unit;
996-
else
997-
ncp->v_align = FILE_ALIGNMENT_DEFAULT;
998-
#endif
993+
/* else ncp->v_align is already set by user/env, ignore the one passed
994+
* by the argument v_align of this subroutine.
995+
*/
999996
}
1000997

1001-
if (ncp->r_align == 0) { /* user info/env does not set nc_record_align_size */
1002-
if (r_align > 0) /* else respect user hint */
998+
if (ncp->r_align == 0) { /* user info does not set nc_record_align_size */
999+
if (r_align > 0) /* r_align is passed from ncmpi__enddef */
10031000
ncp->r_align = r_align;
1004-
#ifdef USE_AGGRESSIVE_ALIGN
1005-
if (striping_unit)
1006-
ncp->r_align = striping_unit;
1007-
else
1008-
ncp->r_align = FILE_ALIGNMENT_DEFAULT;
1009-
#endif
1001+
/* else ncp->r_align is already set by user/env, ignore the one passed
1002+
* by the argument r_align of this subroutine.
1003+
*/
10101004
}
1011-
/* else ncp->r_align is already set by user/env, ignore the one passed by
1012-
* the argument r_align of this subroutine.
1013-
*/
10141005

10151006
/* all CDF formats require 4-bytes alignment */
10161007
if (ncp->h_align == 0) ncp->h_align = 4;
10171008
else ncp->h_align = D_RNDUP(ncp->h_align, 4);
10181009
if (ncp->v_align == 0) ncp->v_align = 4;
10191010
else ncp->v_align = D_RNDUP(ncp->v_align, 4);
1020-
if (ncp->fx_v_align == 0) ncp->fx_v_align = 4;
1021-
else ncp->fx_v_align = D_RNDUP(ncp->fx_v_align, 4);
10221011
if (ncp->r_align == 0) ncp->r_align = 4;
10231012
else ncp->r_align = D_RNDUP(ncp->r_align, 4);
10241013

@@ -1027,7 +1016,7 @@ ncmpio__enddef(void *ncdp,
10271016
*/
10281017
sprintf(value, "%lld", ncp->h_align);
10291018
MPI_Info_set(ncp->mpiinfo, "nc_header_align_size", value);
1030-
sprintf(value, "%lld", ncp->fx_v_align);
1019+
sprintf(value, "%lld", ncp->v_align);
10311020
MPI_Info_set(ncp->mpiinfo, "nc_var_align_size", value);
10321021
sprintf(value, "%lld", ncp->r_align);
10331022
MPI_Info_set(ncp->mpiinfo, "nc_record_align_size", value);

0 commit comments

Comments
 (0)