int MPIO_Err_create_code(int lastcode, int fatal, const char fcname[], int line, int error_class, const char generic_msg[], const char specific_msg[], ... ) { va_list Argp; int idx = 0; char *buf; buf = (char *) ADIOI_Malloc(1024); if (buf != NULL) { idx += ADIOI_Snprintf(buf, 1023, "%s (line %d): ", fcname, line); if (specific_msg == NULL) { ADIOI_Snprintf(&buf[idx], 1023 - idx, "%s\n", generic_msg); } else { va_start(Argp, specific_msg); vsnprintf(&buf[idx], 1023 - idx, specific_msg, Argp); va_end(Argp); } FPRINTF(stderr, "%s", buf); ADIOI_Free(buf); } return error_class; }
/* ADIOI_cb_bcast_rank_map() - broadcast the rank array * * Parameters: * fd - ADIO_File for which update is occurring. cb_nodes and ranklist * parameters must be up-to-date on rank 0 of the fd->comm. * * should probably be a void fn. */ int ADIOI_cb_bcast_rank_map(ADIO_File fd) { int my_rank; char *value; int error_code = MPI_SUCCESS; static char myname[] = "ADIOI_cb_bcast_rank_map"; MPI_Bcast(&(fd->hints->cb_nodes), 1, MPI_INT, 0, fd->comm); if (fd->hints->cb_nodes > 0) { MPI_Comm_rank(fd->comm, &my_rank); if (my_rank != 0) { fd->hints->ranklist = ADIOI_Malloc(fd->hints->cb_nodes*sizeof(int)); if (fd->hints->ranklist == NULL) { error_code = MPIO_Err_create_code(error_code, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_OTHER, "**nomem2",0); return error_code; } } MPI_Bcast(fd->hints->ranklist, fd->hints->cb_nodes, MPI_INT, 0, fd->comm); } /* TEMPORARY -- REMOVE WHEN NO LONGER UPDATING INFO FOR * FS-INDEP. */ value = (char *) ADIOI_Malloc((MPI_MAX_INFO_VAL+1)*sizeof(char)); ADIOI_Snprintf(value, MPI_MAX_INFO_VAL+1, "%d", fd->hints->cb_nodes); ADIOI_Info_set(fd->info, "cb_nodes", value); ADIOI_Free(value); return 0; }
/* ADIOI_cb_bcast_rank_map() - broadcast the rank array * * Parameters: * fd - ADIO_File for which update is occurring. cb_nodes and ranklist * parameters must be up-to-date on rank 0 of the fd->comm. * * should probably be a void fn. */ int ADIOI_cb_bcast_rank_map(ADIO_File fd) { int my_rank; char *value; MPI_Bcast(&(fd->hints->cb_nodes), 1, MPI_INT, 0, fd->comm); if (fd->hints->cb_nodes > 0) { MPI_Comm_rank(fd->comm, &my_rank); if (my_rank != 0) { fd->hints->ranklist = ADIOI_Malloc(fd->hints->cb_nodes*sizeof(int)); if (fd->hints->ranklist == NULL) { /* NEED TO HANDLE ENOMEM */ } } MPI_Bcast(fd->hints->ranklist, fd->hints->cb_nodes, MPI_INT, 0, fd->comm); } /* TEMPORARY -- REMOVE WHEN NO LONGER UPDATING INFO FOR * FS-INDEP. */ value = (char *) ADIOI_Malloc((MPI_MAX_INFO_VAL+1)*sizeof(char)); ADIOI_Snprintf(value, MPI_MAX_INFO_VAL+1, "%d", fd->hints->cb_nodes); ADIOI_Info_set(fd->info, "cb_nodes", value); ADIOI_Free(value); return 0; }
void ADIOI_Shfp_fname(ADIO_File fd, int rank) { double tm; int i, len; char *slash, *ptr, tmp[128]; fd->shared_fp_fname = (char *) ADIOI_Malloc(256); if (!rank) { tm = MPI_Wtime(); while (tm > 1000000000.0) tm -= 1000000000.0; i = (int) tm; tm = tm - (double) i; tm *= 1000000.0; i = (int) tm; ADIOI_Strncpy(fd->shared_fp_fname, fd->filename, 256); #ifdef ROMIO_NTFS slash = strrchr(fd->filename, '\\'); #else slash = strrchr(fd->filename, '/'); #endif if (!slash) { ADIOI_Strncpy(fd->shared_fp_fname, ".", 2); ADIOI_Strncpy(fd->shared_fp_fname + 1, fd->filename, 255); } else { ptr = slash; #ifdef ROMIO_NTFS slash = strrchr(fd->shared_fp_fname, '\\'); #else slash = strrchr(fd->shared_fp_fname, '/'); #endif ADIOI_Strncpy(slash + 1, ".", 2); len = 256 - (slash+2 - fd->shared_fp_fname); ADIOI_Strncpy(slash + 2, ptr + 1, len); } ADIOI_Snprintf(tmp, 128, ".shfp.%d", i); ADIOI_Strnapp(fd->shared_fp_fname, tmp, 256); len = (int)strlen(fd->shared_fp_fname); MPI_Bcast(&len, 1, MPI_INT, 0, fd->comm); MPI_Bcast(fd->shared_fp_fname, len+1, MPI_CHAR, 0, fd->comm); } else { MPI_Bcast(&len, 1, MPI_INT, 0, fd->comm); MPI_Bcast(fd->shared_fp_fname, len+1, MPI_CHAR, 0, fd->comm); } }
void ADIOI_Shfp_fname(ADIO_File fd, int rank, int *error_code) { int i; int len; char *slash, *ptr, tmp[128]; int pid = 0; fd->shared_fp_fname = (char *) ADIOI_Malloc(PATH_MAX); if (!rank) { srand(time(NULL)); i = rand(); pid = (int)getpid(); if (ADIOI_Strncpy(fd->shared_fp_fname, fd->filename, PATH_MAX)) { *error_code = ADIOI_Err_create_code("ADIOI_Shfp_fname", fd->filename, ENAMETOOLONG); return; } #ifdef ROMIO_NTFS slash = strrchr(fd->filename, '\\'); #else slash = strrchr(fd->filename, '/'); #endif if (!slash) { if (ADIOI_Strncpy(fd->shared_fp_fname, ".", 2)) { *error_code = ADIOI_Err_create_code("ADIOI_Shfp_fname", fd->filename, ENAMETOOLONG); return; } if (ADIOI_Strncpy(fd->shared_fp_fname + 1, fd->filename, PATH_MAX-1)) { *error_code = ADIOI_Err_create_code("ADIOI_Shfp_fname", fd->filename, ENAMETOOLONG); return; } } else { ptr = slash; #ifdef ROMIO_NTFS slash = strrchr(fd->shared_fp_fname, '\\'); #else slash = strrchr(fd->shared_fp_fname, '/'); #endif if (ADIOI_Strncpy(slash + 1, ".", 2)) { *error_code = ADIOI_Err_create_code("ADIOI_Shfp_fname", fd->filename, ENAMETOOLONG); return; } /* ok to cast: file names bounded by PATH_MAX and NAME_MAX */ len = (int) (PATH_MAX - (slash+2 - fd->shared_fp_fname)); if (ADIOI_Strncpy(slash + 2, ptr + 1, len)) { *error_code = ADIOI_Err_create_code("ADIOI_Shfp_fname", ptr + 1, ENAMETOOLONG); return; } } ADIOI_Snprintf(tmp, 128, ".shfp.%d.%d", pid, i); /* ADIOI_Strnapp will return non-zero if truncated. That's ok */ ADIOI_Strnapp(fd->shared_fp_fname, tmp, PATH_MAX); len = (int)strlen(fd->shared_fp_fname); MPI_Bcast(&len, 1, MPI_INT, 0, fd->comm); MPI_Bcast(fd->shared_fp_fname, len+1, MPI_CHAR, 0, fd->comm); } else { MPI_Bcast(&len, 1, MPI_INT, 0, fd->comm); MPI_Bcast(fd->shared_fp_fname, len+1, MPI_CHAR, 0, fd->comm); } }
void ADIOI_GEN_SetInfo(ADIO_File fd, MPI_Info users_info, int *error_code) { /* if fd->info is null, create a new info object. Initialize fd->info to default values. Initialize fd->hints to default values. Examine the info object passed by the user. If it contains values that ROMIO understands, override the default. */ MPI_Info info; char *value; int flag, intval, tmp_val, nprocs=0, nprocs_is_valid = 0, len; static char myname[] = "ADIOI_GEN_SETINFO"; if (fd->info == MPI_INFO_NULL) MPI_Info_create(&(fd->info)); info = fd->info; /* Note that fd->hints is allocated at file open time; thus it is * not necessary to allocate it, or check for allocation, here. */ value = (char *) ADIOI_Malloc((MPI_MAX_INFO_VAL+1)*sizeof(char)); if (value == NULL) { /* NEED TO HANDLE ENOMEM */ } /* initialize info and hints to default values if they haven't been * previously initialized */ if (!fd->hints->initialized) { /* buffer size for collective I/O */ MPI_Info_set(info, "cb_buffer_size", ADIOI_CB_BUFFER_SIZE_DFLT); fd->hints->cb_buffer_size = atoi(ADIOI_CB_BUFFER_SIZE_DFLT); /* default is to let romio automatically decide when to use * collective buffering */ MPI_Info_set(info, "romio_cb_read", "automatic"); fd->hints->cb_read = ADIOI_HINT_AUTO; MPI_Info_set(info, "romio_cb_write", "automatic"); fd->hints->cb_write = ADIOI_HINT_AUTO; fd->hints->cb_config_list = NULL; /* number of processes that perform I/O in collective I/O */ MPI_Comm_size(fd->comm, &nprocs); nprocs_is_valid = 1; ADIOI_Snprintf(value, MPI_MAX_INFO_VAL+1, "%d", nprocs); MPI_Info_set(info, "cb_nodes", value); fd->hints->cb_nodes = nprocs; /* hint indicating that no indep. I/O will be performed on this file */ MPI_Info_set(info, "romio_no_indep_rw", "false"); fd->hints->no_indep_rw = 0; /* deferred_open derrived from no_indep_rw and cb_{read,write} */ fd->hints->deferred_open = 0; /* buffer size for data sieving in independent reads */ MPI_Info_set(info, "ind_rd_buffer_size", ADIOI_IND_RD_BUFFER_SIZE_DFLT); fd->hints->ind_rd_buffer_size = atoi(ADIOI_IND_RD_BUFFER_SIZE_DFLT); /* buffer size for data sieving in independent writes */ MPI_Info_set(info, "ind_wr_buffer_size", ADIOI_IND_WR_BUFFER_SIZE_DFLT); fd->hints->ind_wr_buffer_size = atoi(ADIOI_IND_WR_BUFFER_SIZE_DFLT); /* default is to let romio automatically decide when to use data * sieving */ MPI_Info_set(info, "romio_ds_read", "automatic"); fd->hints->ds_read = ADIOI_HINT_AUTO; MPI_Info_set(info, "romio_ds_write", "automatic"); fd->hints->ds_write = ADIOI_HINT_AUTO; fd->hints->initialized = 1; } /* add in user's info if supplied */ if (users_info != MPI_INFO_NULL) { MPI_Info_get(users_info, "cb_buffer_size", MPI_MAX_INFO_VAL, value, &flag); if (flag && ((intval=atoi(value)) > 0)) { tmp_val = intval; MPI_Bcast(&tmp_val, 1, MPI_INT, 0, fd->comm); /* --BEGIN ERROR HANDLING-- */ if (tmp_val != intval) { MPIO_ERR_CREATE_CODE_INFO_NOT_SAME(myname, "cb_buffer_size", error_code); return; } /* --END ERROR HANDLING-- */ MPI_Info_set(info, "cb_buffer_size", value); fd->hints->cb_buffer_size = intval; } /* new hints for enabling/disabling coll. buffering on * reads/writes */ MPI_Info_get(users_info, "romio_cb_read", MPI_MAX_INFO_VAL, value, &flag); if (flag) { if (!strcmp(value, "enable") || !strcmp(value, "ENABLE")) { MPI_Info_set(info, "romio_cb_read", value); fd->hints->cb_read = ADIOI_HINT_ENABLE; } else if (!strcmp(value, "disable") || !strcmp(value, "DISABLE")) { /* romio_cb_read overrides no_indep_rw */ MPI_Info_set(info, "romio_cb_read", value); MPI_Info_set(info, "romio_no_indep_rw", "false"); fd->hints->cb_read = ADIOI_HINT_DISABLE; fd->hints->no_indep_rw = ADIOI_HINT_DISABLE; } else if (!strcmp(value, "automatic") || !strcmp(value, "AUTOMATIC")) { MPI_Info_set(info, "romio_cb_read", value); fd->hints->cb_read = ADIOI_HINT_AUTO; } tmp_val = fd->hints->cb_read; MPI_Bcast(&tmp_val, 1, MPI_INT, 0, fd->comm); /* --BEGIN ERROR HANDLING-- */ if (tmp_val != fd->hints->cb_read) { MPIO_ERR_CREATE_CODE_INFO_NOT_SAME(myname, "romio_cb_read", error_code); return; } /* --END ERROR HANDLING-- */ } MPI_Info_get(users_info, "romio_cb_write", MPI_MAX_INFO_VAL, value, &flag); if (flag) { if (!strcmp(value, "enable") || !strcmp(value, "ENABLE")) { MPI_Info_set(info, "romio_cb_write", value); fd->hints->cb_write = ADIOI_HINT_ENABLE; } else if (!strcmp(value, "disable") || !strcmp(value, "DISABLE")) { /* romio_cb_write overrides no_indep_rw, too */ MPI_Info_set(info, "romio_cb_write", value); MPI_Info_set(info, "romio_no_indep_rw", "false"); fd->hints->cb_write = ADIOI_HINT_DISABLE; fd->hints->no_indep_rw = ADIOI_HINT_DISABLE; } else if (!strcmp(value, "automatic") || !strcmp(value, "AUTOMATIC")) { MPI_Info_set(info, "romio_cb_write", value); fd->hints->cb_write = ADIOI_HINT_AUTO; } tmp_val = fd->hints->cb_write; MPI_Bcast(&tmp_val, 1, MPI_INT, 0, fd->comm); /* --BEGIN ERROR HANDLING-- */ if (tmp_val != fd->hints->cb_write) { MPIO_ERR_CREATE_CODE_INFO_NOT_SAME(myname, "romio_cb_write", error_code); return; } /* --END ERROR HANDLING-- */ } /* new hint for specifying no indep. read/write will be performed */ MPI_Info_get(users_info, "romio_no_indep_rw", MPI_MAX_INFO_VAL, value, &flag); if (flag) { if (!strcmp(value, "true") || !strcmp(value, "TRUE")) { /* if 'no_indep_rw' set, also hint that we will do * collective buffering: if we aren't doing independent io, * then we have to do collective */ MPI_Info_set(info, "romio_no_indep_rw", value); MPI_Info_set(info, "romio_cb_write", "enable"); MPI_Info_set(info, "romio_cb_read", "enable"); fd->hints->no_indep_rw = 1; fd->hints->cb_read = 1; fd->hints->cb_write = 1; tmp_val = 1; } else if (!strcmp(value, "false") || !strcmp(value, "FALSE")) { MPI_Info_set(info, "romio_no_indep_rw", value); fd->hints->no_indep_rw = 0; tmp_val = 0; } else { /* default is above */ tmp_val = 0; } MPI_Bcast(&tmp_val, 1, MPI_INT, 0, fd->comm); /* --BEGIN ERROR HANDLING-- */ if (tmp_val != fd->hints->no_indep_rw) { MPIO_ERR_CREATE_CODE_INFO_NOT_SAME(myname, "romio_no_indep_rw", error_code); return; } /* --END ERROR HANDLING-- */ } /* new hints for enabling/disabling data sieving on * reads/writes */ MPI_Info_get(users_info, "romio_ds_read", MPI_MAX_INFO_VAL, value, &flag); if (flag) { if (!strcmp(value, "enable") || !strcmp(value, "ENABLE")) { MPI_Info_set(info, "romio_ds_read", value); fd->hints->ds_read = ADIOI_HINT_ENABLE; } else if (!strcmp(value, "disable") || !strcmp(value, "DISABLE")) { MPI_Info_set(info, "romio_ds_read", value); fd->hints->ds_read = ADIOI_HINT_DISABLE; } else if (!strcmp(value, "automatic") || !strcmp(value, "AUTOMATIC")) { MPI_Info_set(info, "romio_ds_read", value); fd->hints->ds_read = ADIOI_HINT_AUTO; } /* otherwise ignore */ } MPI_Info_get(users_info, "romio_ds_write", MPI_MAX_INFO_VAL, value, &flag); if (flag) { if (!strcmp(value, "enable") || !strcmp(value, "ENABLE")) { MPI_Info_set(info, "romio_ds_write", value); fd->hints->ds_write = ADIOI_HINT_ENABLE; } else if (!strcmp(value, "disable") || !strcmp(value, "DISABLE")) { MPI_Info_set(info, "romio_ds_write", value); fd->hints->ds_write = ADIOI_HINT_DISABLE; } else if (!strcmp(value, "automatic") || !strcmp(value, "AUTOMATIC")) { MPI_Info_set(info, "romio_ds_write", value); fd->hints->ds_write = ADIOI_HINT_AUTO; } /* otherwise ignore */ } MPI_Info_get(users_info, "cb_nodes", MPI_MAX_INFO_VAL, value, &flag); if (flag && ((intval=atoi(value)) > 0)) { tmp_val = intval; MPI_Bcast(&tmp_val, 1, MPI_INT, 0, fd->comm); /* --BEGIN ERROR HANDLING-- */ if (tmp_val != intval) { MPIO_ERR_CREATE_CODE_INFO_NOT_SAME(myname, "cb_nodes", error_code); return; } /* --END ERROR HANDLING-- */ if (!nprocs_is_valid) { /* if hints were already initialized, we might not * have already gotten this? */ MPI_Comm_size(fd->comm, &nprocs); nprocs_is_valid = 1; } if (intval <= nprocs) { MPI_Info_set(info, "cb_nodes", value); fd->hints->cb_nodes = intval; } } MPI_Info_get(users_info, "ind_wr_buffer_size", MPI_MAX_INFO_VAL, value, &flag); if (flag && ((intval = atoi(value)) > 0)) { MPI_Info_set(info, "ind_wr_buffer_size", value); fd->hints->ind_wr_buffer_size = intval; } MPI_Info_get(users_info, "ind_rd_buffer_size", MPI_MAX_INFO_VAL, value, &flag); if (flag && ((intval = atoi(value)) > 0)) { MPI_Info_set(info, "ind_rd_buffer_size", value); fd->hints->ind_rd_buffer_size = intval; } MPI_Info_get(users_info, "cb_config_list", MPI_MAX_INFO_VAL, value, &flag); if (flag) { if (fd->hints->cb_config_list == NULL) { /* only set cb_config_list if it isn't already set. * Note that since we set it below, this ensures that * the cb_config_list hint will be set at file open time * either by the user or to the default */ MPI_Info_set(info, "cb_config_list", value); len = (strlen(value)+1) * sizeof(char); fd->hints->cb_config_list = ADIOI_Malloc(len); if (fd->hints->cb_config_list == NULL) { /* NEED TO HANDLE ENOMEM */ } ADIOI_Strncpy(fd->hints->cb_config_list, value, len); } /* if it has been set already, we ignore it the second time. * otherwise we would get an error if someone used the same * info value with a cb_config_list value in it in a couple * of calls, which would be irritating. */ } } /* handle cb_config_list default value here; avoids an extra * free/alloc and insures it is always set */ if (fd->hints->cb_config_list == NULL) { MPI_Info_set(info, "cb_config_list", ADIOI_CB_CONFIG_LIST_DFLT); len = (strlen(ADIOI_CB_CONFIG_LIST_DFLT)+1) * sizeof(char); fd->hints->cb_config_list = ADIOI_Malloc(len); if (fd->hints->cb_config_list == NULL) { /* NEED TO HANDLE ENOMEM */ } ADIOI_Strncpy(fd->hints->cb_config_list, ADIOI_CB_CONFIG_LIST_DFLT, len); } /* deferred_open won't be set by callers, but if the user doesn't * explicitly disable collecitve buffering (two-phase) and does hint that * io w/o independent io is going on, we'll set this internal hint as a * convenience */ if ( ( (fd->hints->cb_read != ADIOI_HINT_DISABLE) \ && (fd->hints->cb_write != ADIOI_HINT_DISABLE)\ && fd->hints->no_indep_rw ) ) { fd->hints->deferred_open = 1; } else { /* setting romio_no_indep_rw enable and romio_cb_{read,write} * disable at the same time doesn't make sense. honor * romio_cb_{read,write} and force the no_indep_rw hint to * 'disable' */ MPI_Info_set(info, "romio_no_indep_rw", "false"); fd->hints->no_indep_rw = 0; fd->hints->deferred_open = 0; } if ((fd->file_system == ADIO_PIOFS) || (fd->file_system == ADIO_PVFS) || (fd->file_system == ADIO_PVFS2) ) { /* no data sieving for writes in PIOFS, PVFS and PVFS2, because they do not support file locking */ MPI_Info_get(info, "ind_wr_buffer_size", MPI_MAX_INFO_VAL, value, &flag); if (flag) { /* get rid of this value if it is set */ MPI_Info_delete(info, "ind_wr_buffer_size"); } /* note: leave ind_wr_buffer_size alone; used for other cases * as well. -- Rob Ross, 04/22/2003 */ MPI_Info_set(info, "romio_ds_write", "disable"); fd->hints->ds_write = ADIOI_HINT_DISABLE; } ADIOI_Free(value); *error_code = MPI_SUCCESS; }
int MPIO_Err_return_file(MPI_File mpi_fh, int error_code) { MPI_Errhandler e; void (*c_errhandler)(MPI_File *, int *, ... ); int kind; /* Error handler kind (see below) */ char error_msg[4096]; int len; /* If the file pointer is not valid, we use the handler on MPI_FILE_NULL (MPI-2, section 9.7). For now, this code assumes that MPI_FILE_NULL has the default handler (return). FIXME. See below - the set error handler uses ADIOI_DFLT_ERR_HANDLER; */ /* First, get the handler and the corresponding function */ if (mpi_fh == MPI_FILE_NULL) { e = ADIOI_DFLT_ERR_HANDLER; } else { ADIO_File fh; fh = MPIO_File_resolve(mpi_fh); e = fh->err_handler; } /* Actually, e is just the value provide by the MPICH routines file_set_errhandler. This is actually a *pointer* to the errhandler structure. We don't know that, so we ask the MPICH code to translate this object into an error handler. kind = 0: errors are fatal kind = 1: errors return kind = 2: errors call function */ if (e == MPI_ERRORS_RETURN || e == MPIR_ERRORS_THROW_EXCEPTIONS || !e) { /* FIXME: This is a hack in case no error handler was set */ kind = 1; c_errhandler = 0; } else { MPIR_Get_file_error_routine( e, &c_errhandler, &kind ); } /* --BEGIN ERROR HANDLING-- */ if (MPIR_Err_is_fatal(error_code) || kind == 0) { ADIOI_Snprintf(error_msg, 4096, "I/O error: "); len = (int)strlen(error_msg); MPIR_Err_get_string(error_code, &error_msg[len], 4096-len, NULL); MPID_Abort(NULL, MPI_SUCCESS, error_code, error_msg); } /* --END ERROR HANDLING-- */ else if (kind == 2) { (*c_errhandler)( &mpi_fh, &error_code, 0 ); } else if (kind == 3) { MPIR_File_call_cxx_errhandler( &mpi_fh, &error_code, c_errhandler ); } /* kind == 1 just returns */ return error_code; }
void ADIOI_PFS_Open(ADIO_File fd, int *error_code) { int perm, amode, old_mask, np_comm, np_total, err, flag; char *value; struct sattr attr; static char myname[] = "ADIOI_PFS_OPEN"; if (fd->perm == ADIO_PERM_NULL) { old_mask = umask(022); umask(old_mask); perm = old_mask ^ 0666; } else perm = fd->perm; amode = 0; if (fd->access_mode & ADIO_CREATE) amode = amode | O_CREAT; if (fd->access_mode & ADIO_RDONLY) amode = amode | O_RDONLY; if (fd->access_mode & ADIO_WRONLY) amode = amode | O_WRONLY; if (fd->access_mode & ADIO_RDWR) amode = amode | O_RDWR; if (fd->access_mode & ADIO_EXCL) amode = amode | O_EXCL; MPI_Comm_size(MPI_COMM_WORLD, &np_total); MPI_Comm_size(fd->comm, &np_comm); if (np_total == np_comm) fd->fd_sys = _gopen(fd->filename, amode, M_ASYNC, perm); else fd->fd_sys = open(fd->filename, amode, perm); fd->fd_direct = -1; if (fd->fd_sys != -1) { value = (char *) ADIOI_Malloc((MPI_MAX_INFO_VAL+1)*sizeof(char)); /* if user has asked for pfs server buffering to be turned on, it will be set to true in fd->info in the earlier call to ADIOI_PFS_SetInfo. Turn it on now, since we now have a valid file descriptor. */ MPI_Info_get(fd->info, "pfs_svr_buf", MPI_MAX_INFO_VAL, value, &flag); if (flag && (!strcmp(value, "true"))) { err = fcntl(fd->fd_sys, F_PFS_SVR_BUF, TRUE); if (err) MPI_Info_set(fd->info, "pfs_svr_buf", "false"); } /* get file striping information and set it in info */ err = fcntl(fd->fd_sys, F_GETSATTR, &attr); if (!err) { ADIOI_Snprintf(value, MPI_MAX_INFO_VAL+1, "%d", attr.s_sunitsize); MPI_Info_set(fd->info, "striping_unit", value); ADIOI_Snprintf(value, MPI_MAX_INFO_VAL+1, "%d", attr.s_sfactor); MPI_Info_set(fd->info, "striping_factor", value); ADIOI_Snprintf(value, MPI_MAX_INFO_VAL+1, "%d", attr.s_start_sdir); MPI_Info_set(fd->info, "start_iodevice", value); } ADIOI_Free(value); if (fd->access_mode & ADIO_APPEND) fd->fp_ind = fd->fp_sys_posn = lseek(fd->fd_sys, 0, SEEK_END); } if (fd->fd_sys == -1) { *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io", "**io %s", strerror(errno)); } else *error_code = MPI_SUCCESS; }
void ADIOI_BGL_SetInfo(ADIO_File fd, MPI_Info users_info, int *error_code) { /* if fd->info is null, create a new info object. Initialize fd->info to default values. Initialize fd->hints to default values. Examine the info object passed by the user. If it contains values that ROMIO understands, override the default. */ MPI_Info info; char *value; int flag, intval, tmp_val, nprocs=0, nprocs_is_valid = 0; static char myname[] = "ADIOI_BGL_SETINFO"; int did_anything = 0; if (fd->info == MPI_INFO_NULL) MPI_Info_create(&(fd->info)); info = fd->info; /* Note that fd->hints is allocated at file open time; thus it is * not necessary to allocate it, or check for allocation, here. */ value = (char *) ADIOI_Malloc((MPI_MAX_INFO_VAL+1)*sizeof(char)); AD_BGL_assert ((value != NULL)); /* initialize info and hints to default values if they haven't been * previously initialized */ if (!fd->hints->initialized) { did_anything = 1; /* buffer size for collective I/O */ ADIOI_Info_set(info, "cb_buffer_size", ADIOI_BGL_CB_BUFFER_SIZE_DFLT); fd->hints->cb_buffer_size = atoi(ADIOI_BGL_CB_BUFFER_SIZE_DFLT); /* default is to let romio automatically decide when to use * collective buffering */ ADIOI_Info_set(info, "romio_cb_read", "enable"); fd->hints->cb_read = ADIOI_HINT_ENABLE; ADIOI_Info_set(info, "romio_cb_write", "enable"); fd->hints->cb_write = ADIOI_HINT_ENABLE; if ( fd->hints->cb_config_list != NULL ) ADIOI_Free (fd->hints->cb_config_list); fd->hints->cb_config_list = NULL; /* number of processes that perform I/O in collective I/O */ MPI_Comm_size(fd->comm, &nprocs); nprocs_is_valid = 1; ADIOI_Snprintf(value, MPI_MAX_INFO_VAL+1, "%d", nprocs); ADIOI_Info_set(info, "cb_nodes", value); fd->hints->cb_nodes = -1; /* hint indicating that no indep. I/O will be performed on this file */ ADIOI_Info_set(info, "romio_no_indep_rw", "false"); fd->hints->no_indep_rw = 0; /* bgl is not implementing file realms (ADIOI_IOStridedColl), initialize to disabled it. */ /* hint instructing the use of persistent file realms */ ADIOI_Info_set(info, "romio_cb_pfr", "disable"); fd->hints->cb_pfr = ADIOI_HINT_DISABLE; /* hint guiding the assignment of persistent file realms */ ADIOI_Info_set(info, "romio_cb_fr_types", "aar"); fd->hints->cb_fr_type = ADIOI_FR_AAR; /* hint to align file realms with a certain byte value */ ADIOI_Info_set(info, "romio_cb_fr_alignment", "1"); fd->hints->cb_fr_alignment = 1; /* hint to set a threshold percentage for a datatype's size/extent at * which data sieving should be done in collective I/O */ ADIOI_Info_set(info, "romio_cb_ds_threshold", "0"); fd->hints->cb_ds_threshold = 0; /* hint to switch between point-to-point or all-to-all for two-phase */ ADIOI_Info_set(info, "romio_cb_alltoall", "automatic"); fd->hints->cb_alltoall = ADIOI_HINT_AUTO; /* deferred_open derived from no_indep_rw and cb_{read,write} */ fd->hints->deferred_open = 0; /* buffer size for data sieving in independent reads */ ADIOI_Info_set(info, "ind_rd_buffer_size", ADIOI_BGL_IND_RD_BUFFER_SIZE_DFLT); fd->hints->ind_rd_buffer_size = atoi(ADIOI_BGL_IND_RD_BUFFER_SIZE_DFLT); /* buffer size for data sieving in independent writes */ ADIOI_Info_set(info, "ind_wr_buffer_size", ADIOI_BGL_IND_WR_BUFFER_SIZE_DFLT); fd->hints->ind_wr_buffer_size = atoi(ADIOI_BGL_IND_WR_BUFFER_SIZE_DFLT); if(fd->file_system == ADIO_UFS) { /* default for ufs/pvfs is to disable data sieving */ ADIOI_Info_set(info, "romio_ds_read", "disable"); fd->hints->ds_read = ADIOI_HINT_DISABLE; ADIOI_Info_set(info, "romio_ds_write", "disable"); fd->hints->ds_write = ADIOI_HINT_DISABLE; } else { /* default is to let romio automatically decide when to use data * sieving */ ADIOI_Info_set(info, "romio_ds_read", "automatic"); fd->hints->ds_read = ADIOI_HINT_AUTO; ADIOI_Info_set(info, "romio_ds_write", "automatic"); fd->hints->ds_write = ADIOI_HINT_AUTO; } /* still to do: tune this a bit for a variety of file systems. there's * no good default value so just leave it unset */ fd->hints->min_fdomain_size = 0; fd->hints->striping_unit = 0; fd->hints->initialized = 1; } /* add in user's info if supplied */ if (users_info != MPI_INFO_NULL) { ADIOI_Info_get(users_info, "cb_buffer_size", MPI_MAX_INFO_VAL, value, &flag); if (flag && ((intval=atoi(value)) > 0)) { tmp_val = intval; MPI_Bcast(&tmp_val, 1, MPI_INT, 0, fd->comm); /* --BEGIN ERROR HANDLING-- */ if (tmp_val != intval) { MPIO_ERR_CREATE_CODE_INFO_NOT_SAME(myname, "cb_buffer_size", error_code); return; } /* --END ERROR HANDLING-- */ ADIOI_Info_set(info, "cb_buffer_size", value); fd->hints->cb_buffer_size = intval; } #if 0 /* bgl is not implementing file realms (ADIOI_IOStridedColl) ... */ /* aligning file realms to certain sizes (e.g. stripe sizes) * may benefit I/O performance */ ADIOI_Info_get(users_info, "romio_cb_fr_alignment", MPI_MAX_INFO_VAL, value, &flag); if (flag && ((intval=atoi(value)) > 0)) { tmp_val = intval; MPI_Bcast(&tmp_val, 1, MPI_INT, 0, fd->comm); /* --BEGIN ERROR HANDLING-- */ if (tmp_val != intval) { MPIO_ERR_CREATE_CODE_INFO_NOT_SAME(myname, "romio_cb_fr_alignment", error_code); return; } /* --END ERROR HANDLING-- */ ADIOI_Info_set(info, "romio_cb_fr_alignment", value); fd->hints->cb_fr_alignment = intval; } /* for collective I/O, try to be smarter about when to do data sieving * using a specific threshold for the datatype size/extent * (percentage 0-100%) */ ADIOI_Info_get(users_info, "romio_cb_ds_threshold", MPI_MAX_INFO_VAL, value, &flag); if (flag && ((intval=atoi(value)) > 0)) { tmp_val = intval; MPI_Bcast(&tmp_val, 1, MPI_INT, 0, fd->comm); /* --BEGIN ERROR HANDLING-- */ if (tmp_val != intval) { MPIO_ERR_CREATE_CODE_INFO_NOT_SAME(myname, "romio_cb_ds_threshold", error_code); return; } /* --END ERROR HANDLING-- */ ADIOI_Info_set(info, "romio_cb_ds_threshold", value); fd->hints->cb_ds_threshold = intval; } ADIOI_Info_get(users_info, "romio_cb_alltoall", MPI_MAX_INFO_VAL, value, &flag); if (flag) { if (!strcmp(value, "enable") || !strcmp(value, "ENABLE")) { ADIOI_Info_set(info, "romio_cb_alltoall", value); fd->hints->cb_read = ADIOI_HINT_ENABLE; } else if (!strcmp(value, "disable") || !strcmp(value, "DISABLE")) { ADIOI_Info_set(info, "romio_cb_alltoall", value); fd->hints->cb_read = ADIOI_HINT_DISABLE; } else if (!strcmp(value, "automatic") || !strcmp(value, "AUTOMATIC")) { ADIOI_Info_set(info, "romio_cb_alltoall", value); fd->hints->cb_read = ADIOI_HINT_AUTO; } tmp_val = fd->hints->cb_alltoall; MPI_Bcast(&tmp_val, 1, MPI_INT, 0, fd->comm); /* --BEGIN ERROR HANDLING-- */ if (tmp_val != fd->hints->cb_alltoall) { MPIO_ERR_CREATE_CODE_INFO_NOT_SAME(myname, "romio_cb_alltoall", error_code); return; } /* --END ERROR HANDLING-- */ } #endif /* new hints for enabling/disabling coll. buffering on * reads/writes */ ADIOI_Info_get(users_info, "romio_cb_read", MPI_MAX_INFO_VAL, value, &flag); if (flag) { if (!strcmp(value, "enable") || !strcmp(value, "ENABLE")) { ADIOI_Info_set(info, "romio_cb_read", value); fd->hints->cb_read = ADIOI_HINT_ENABLE; } else if (!strcmp(value, "disable") || !strcmp(value, "DISABLE")) { /* romio_cb_read overrides no_indep_rw */ ADIOI_Info_set(info, "romio_cb_read", value); ADIOI_Info_set(info, "romio_no_indep_rw", "false"); fd->hints->cb_read = ADIOI_HINT_DISABLE; fd->hints->no_indep_rw = ADIOI_HINT_DISABLE; } else if (!strcmp(value, "automatic") || !strcmp(value, "AUTOMATIC")) { ADIOI_Info_set(info, "romio_cb_read", value); fd->hints->cb_read = ADIOI_HINT_AUTO; } tmp_val = fd->hints->cb_read; MPI_Bcast(&tmp_val, 1, MPI_INT, 0, fd->comm); /* --BEGIN ERROR HANDLING-- */ if (tmp_val != fd->hints->cb_read) { MPIO_ERR_CREATE_CODE_INFO_NOT_SAME(myname, "romio_cb_read", error_code); return; } /* --END ERROR HANDLING-- */ } ADIOI_Info_get(users_info, "romio_cb_write", MPI_MAX_INFO_VAL, value, &flag); if (flag) { if (!strcmp(value, "enable") || !strcmp(value, "ENABLE")) { ADIOI_Info_set(info, "romio_cb_write", value); fd->hints->cb_write = ADIOI_HINT_ENABLE; } else if (!strcmp(value, "disable") || !strcmp(value, "DISABLE")) { /* romio_cb_write overrides no_indep_rw, too */ ADIOI_Info_set(info, "romio_cb_write", value); ADIOI_Info_set(info, "romio_no_indep_rw", "false"); fd->hints->cb_write = ADIOI_HINT_DISABLE; fd->hints->no_indep_rw = ADIOI_HINT_DISABLE; } else if (!strcmp(value, "automatic") || !strcmp(value, "AUTOMATIC")) { ADIOI_Info_set(info, "romio_cb_write", value); fd->hints->cb_write = ADIOI_HINT_AUTO; } tmp_val = fd->hints->cb_write; MPI_Bcast(&tmp_val, 1, MPI_INT, 0, fd->comm); /* --BEGIN ERROR HANDLING-- */ if (tmp_val != fd->hints->cb_write) { MPIO_ERR_CREATE_CODE_INFO_NOT_SAME(myname, "romio_cb_write", error_code); return; } /* --END ERROR HANDLING-- */ } #if 0 /* bgl is not implementing file realms (ADIOI_IOStridedColl) ... */ /* enable/disable persistent file realms for collective I/O */ /* may want to check for no_indep_rdwr hint as well */ ADIOI_Info_get(users_info, "romio_cb_pfr", MPI_MAX_INFO_VAL, value, &flag); if (flag) { if (!strcmp(value, "enable") || !strcmp(value, "ENABLE")) { ADIOI_Info_set(info, "romio_cb_pfr", value); fd->hints->cb_pfr = ADIOI_HINT_ENABLE; } else if (!strcmp(value, "disable") || !strcmp(value, "DISABLE")) { ADIOI_Info_set(info, "romio_cb_pfr", value); fd->hints->cb_pfr = ADIOI_HINT_DISABLE; } else if (!strcmp(value, "automatic") || !strcmp(value, "AUTOMATIC")) { ADIOI_Info_set(info, "romio_cb_pfr", value); fd->hints->cb_pfr = ADIOI_HINT_AUTO; } tmp_val = fd->hints->cb_pfr; MPI_Bcast(&tmp_val, 1, MPI_INT, 0, fd->comm); /* --BEGIN ERROR HANDLING-- */ if (tmp_val != fd->hints->cb_pfr) { MPIO_ERR_CREATE_CODE_INFO_NOT_SAME(myname, "romio_cb_pfr", error_code); return; } /* --END ERROR HANDLING-- */ } /* file realm assignment types ADIOI_FR_AAR(0), ADIOI_FR_FSZ(-1), ADIOI_FR_USR_REALMS(-2), all others specify a regular fr size in bytes. probably not the best way... */ ADIOI_Info_get(users_info, "romio_cb_fr_type", MPI_MAX_INFO_VAL, value, &flag); if (flag && ((intval=atoi(value)) >= -2)) { tmp_val = intval; MPI_Bcast(&tmp_val, 1, MPI_INT, 0, fd->comm); /* --BEGIN ERROR HANDLING-- */ if (tmp_val != intval) { MPIO_ERR_CREATE_CODE_INFO_NOT_SAME(myname, "romio_cb_fr_type", error_code); return; } /* --END ERROR HANDLING-- */ ADIOI_Info_set(info, "romio_cb_fr_type", value); fd->hints->cb_fr_type = intval; } #endif /* new hint for specifying no indep. read/write will be performed */ ADIOI_Info_get(users_info, "romio_no_indep_rw", MPI_MAX_INFO_VAL, value, &flag); if (flag) { if (!strcmp(value, "true") || !strcmp(value, "TRUE")) { /* if 'no_indep_rw' set, also hint that we will do * collective buffering: if we aren't doing independent io, * then we have to do collective */ ADIOI_Info_set(info, "romio_no_indep_rw", value); ADIOI_Info_set(info, "romio_cb_write", "enable"); ADIOI_Info_set(info, "romio_cb_read", "enable"); fd->hints->no_indep_rw = 1; fd->hints->cb_read = 1; fd->hints->cb_write = 1; tmp_val = 1; } else if (!strcmp(value, "false") || !strcmp(value, "FALSE")) { ADIOI_Info_set(info, "romio_no_indep_rw", value); fd->hints->no_indep_rw = 0; tmp_val = 0; } else { /* default is above */ tmp_val = 0; } MPI_Bcast(&tmp_val, 1, MPI_INT, 0, fd->comm); /* --BEGIN ERROR HANDLING-- */ if (tmp_val != fd->hints->no_indep_rw) { MPIO_ERR_CREATE_CODE_INFO_NOT_SAME(myname, "romio_no_indep_rw", error_code); return; } /* --END ERROR HANDLING-- */ } /* new hints for enabling/disabling data sieving on * reads/writes */ ADIOI_Info_get(users_info, "romio_ds_read", MPI_MAX_INFO_VAL, value, &flag); if (flag) { if (!strcmp(value, "enable") || !strcmp(value, "ENABLE")) { ADIOI_Info_set(info, "romio_ds_read", value); fd->hints->ds_read = ADIOI_HINT_ENABLE; } else if (!strcmp(value, "disable") || !strcmp(value, "DISABLE")) { ADIOI_Info_set(info, "romio_ds_read", value); fd->hints->ds_read = ADIOI_HINT_DISABLE; } else if (!strcmp(value, "automatic") || !strcmp(value, "AUTOMATIC")) { ADIOI_Info_set(info, "romio_ds_read", value); fd->hints->ds_read = ADIOI_HINT_AUTO; } /* otherwise ignore */ } ADIOI_Info_get(users_info, "romio_ds_write", MPI_MAX_INFO_VAL, value, &flag); if (flag) { if (!strcmp(value, "enable") || !strcmp(value, "ENABLE")) { ADIOI_Info_set(info, "romio_ds_write", value); fd->hints->ds_write = ADIOI_HINT_ENABLE; } else if (!strcmp(value, "disable") || !strcmp(value, "DISABLE")) { ADIOI_Info_set(info, "romio_ds_write", value); fd->hints->ds_write = ADIOI_HINT_DISABLE; } else if (!strcmp(value, "automatic") || !strcmp(value, "AUTOMATIC")) { ADIOI_Info_set(info, "romio_ds_write", value); fd->hints->ds_write = ADIOI_HINT_AUTO; } /* otherwise ignore */ } ADIOI_Info_get(users_info, "ind_wr_buffer_size", MPI_MAX_INFO_VAL, value, &flag); if (flag && ((intval = atoi(value)) > 0)) { ADIOI_Info_set(info, "ind_wr_buffer_size", value); fd->hints->ind_wr_buffer_size = intval; } ADIOI_Info_get(users_info, "ind_rd_buffer_size", MPI_MAX_INFO_VAL, value, &flag); if (flag && ((intval = atoi(value)) > 0)) { ADIOI_Info_set(info, "ind_rd_buffer_size", value); fd->hints->ind_rd_buffer_size = intval; } memset( value, 0, MPI_MAX_INFO_VAL+1 ); ADIOI_Info_get(users_info, "romio_min_fdomain_size", MPI_MAX_INFO_VAL, value, &flag); if ( flag && ((intval = atoi(value)) > 0) ) { ADIOI_Info_set(info, "romio_min_fdomain_size", value); fd->hints->min_fdomain_size = intval; } /* Now we use striping unit in common code so we should process hints for it. */ ADIOI_Info_get(users_info, "striping_unit", MPI_MAX_INFO_VAL, value, &flag); if ( flag && ((intval = atoi(value)) > 0) ) { ADIOI_Info_set(info, "striping_unit", value); fd->hints->striping_unit = intval; } memset( value, 0, MPI_MAX_INFO_VAL+1 ); ADIOI_Info_get(users_info, ADIOI_BGL_NAGG_IN_PSET_HINT_NAME, MPI_MAX_INFO_VAL, value, &flag); if (flag && ((intval = atoi(value)) > 0)) { did_anything = 1; ADIOI_Info_set(info, ADIOI_BGL_NAGG_IN_PSET_HINT_NAME, value); fd->hints->cb_nodes = intval; } } /* associate CB aggregators to certain CNs in every involved PSET */ if (did_anything) { ADIOI_BGL_gen_agg_ranklist(fd, fd->hints->cb_nodes); } /* ignore defered open hints and do not enable it for bluegene: need all * processors in the open path so we can stat-and-broadcast the blocksize */ ADIOI_Info_set(info, "romio_no_indep_rw", "false"); fd->hints->no_indep_rw = 0; fd->hints->deferred_open = 0; /* BobC commented this out, but since hint processing runs on both bgl and * bglockless, we need to keep DS writes enabled on gpfs and disabled on * PVFS */ if (ADIO_Feature(fd, ADIO_DATA_SIEVING_WRITES) == 0) { /* disable data sieving for fs that do not support file locking */ ADIOI_Info_get(info, "ind_wr_buffer_size", MPI_MAX_INFO_VAL, value, &flag); if (flag) { /* get rid of this value if it is set */ ADIOI_Info_delete(info, "ind_wr_buffer_size"); } /* note: leave ind_wr_buffer_size alone; used for other cases * as well. -- Rob Ross, 04/22/2003 */ ADIOI_Info_set(info, "romio_ds_write", "disable"); fd->hints->ds_write = ADIOI_HINT_DISABLE; } ADIOI_Free(value); *error_code = MPI_SUCCESS; }
void ADIOI_PANFS_Open(ADIO_File fd, int *error_code) { char* value; int perm, old_mask, amode, flag; static char myname[] = "ADIOI_PANFS_OPEN"; if (fd->perm == ADIO_PERM_NULL) { old_mask = umask(022); umask(old_mask); perm = ~old_mask & 0666; } else perm = fd->perm; amode = 0; if (fd->access_mode & ADIO_CREATE) { pan_fs_client_layout_agg_type_t layout_type = PAN_FS_CLIENT_LAYOUT_TYPE__DEFAULT; unsigned long int layout_stripe_unit = 0; unsigned long int layout_parity_stripe_width = 0; unsigned long int layout_parity_stripe_depth = 0; unsigned long int layout_total_num_comps = 0; pan_fs_client_layout_visit_t layout_visit_policy = PAN_FS_CLIENT_LAYOUT_VISIT__ROUND_ROBIN; int myrank; MPI_Comm_rank(fd->comm, &myrank); *error_code = MPI_SUCCESS; value = (char *) ADIOI_Malloc((MPI_MAX_INFO_VAL+1)*sizeof(char)); ADIOI_Info_get(fd->info, "panfs_layout_type", MPI_MAX_INFO_VAL, value, &flag); if (flag) { layout_type = strtoul(value,NULL,10); } ADIOI_Info_get(fd->info, "panfs_layout_stripe_unit", MPI_MAX_INFO_VAL, value, &flag); if (flag) { layout_stripe_unit = strtoul(value,NULL,10); } ADIOI_Info_get(fd->info, "panfs_layout_total_num_comps", MPI_MAX_INFO_VAL, value, &flag); if (flag) { layout_total_num_comps = strtoul(value,NULL,10); } ADIOI_Info_get(fd->info, "panfs_layout_parity_stripe_width", MPI_MAX_INFO_VAL, value, &flag); if (flag) { layout_parity_stripe_width = strtoul(value,NULL,10); } ADIOI_Info_get(fd->info, "panfs_layout_parity_stripe_depth", MPI_MAX_INFO_VAL, value, &flag); if (flag) { layout_parity_stripe_depth = strtoul(value,NULL,10); } ADIOI_Info_get(fd->info, "panfs_layout_visit_policy", MPI_MAX_INFO_VAL, value, &flag); if (flag) { layout_visit_policy = strtoul(value,NULL,10); } ADIOI_Free(value); amode = amode | O_CREAT; /* Check for valid set of hints */ if ((layout_type < PAN_FS_CLIENT_LAYOUT_TYPE__DEFAULT) || (layout_type > PAN_FS_CLIENT_LAYOUT_TYPE__RAID10)) { FPRINTF(stderr, "%s: panfs_layout_type is not a valid value: %u.\n", myname, layout_type); MPI_Abort(MPI_COMM_WORLD, 1); } if ((layout_type == PAN_FS_CLIENT_LAYOUT_TYPE__RAID0) && ((layout_stripe_unit == 0) || (layout_total_num_comps == 0))) { if(layout_stripe_unit == 0) { FPRINTF(stderr, "%s: MPI_Info does not contain the panfs_layout_stripe_unit hint which is necessary to specify a valid RAID0 layout to the PAN_FS_CLIENT_LAYOUT_CREATE_FILE ioctl.\n", myname); } if(layout_total_num_comps == 0) { FPRINTF(stderr, "%s: MPI_Info does not contain the panfs_layout_total_num_comps hint which is necessary to specify a valid RAID0 layout to the PAN_FS_CLIENT_LAYOUT_CREATE_FILE ioctl.\n", myname); } MPI_Abort(MPI_COMM_WORLD, 1); } if (layout_type == PAN_FS_CLIENT_LAYOUT_TYPE__RAID1_5_PARITY_STRIPE) { if ((layout_stripe_unit == 0) || (layout_parity_stripe_width == 0) || (layout_parity_stripe_depth == 0) || (layout_total_num_comps == 0)) { if(layout_stripe_unit == 0) { FPRINTF(stderr, "%s: MPI_Info does not contain the panfs_layout_stripe_unit hint which is necessary to specify a valid RAID5 parity stripe layout to the PAN_FS_CLIENT_LAYOUT_CREATE_FILE ioctl.\n", myname); } if(layout_total_num_comps == 0) { FPRINTF(stderr, "%s: MPI_Info does not contain the panfs_layout_total_num_comps hint which is necessary to specify a valid RAID5 parity stripe layout to the PAN_FS_CLIENT_LAYOUT_CREATE_FILE ioctl.\n", myname); } if(layout_parity_stripe_width == 0) { FPRINTF(stderr, "%s: MPI_Info does not contain the panfs_layout_parity_stripe_width hint which is necessary to specify a valid RAID5 parity stripe layout to the PAN_FS_CLIENT_LAYOUT_CREATE_FILE ioctl.\n", myname); } if(layout_parity_stripe_depth == 0) { FPRINTF(stderr, "%s: MPI_Info does not contain the panfs_layout_parity_stripe_depth hint which is necessary to specify a valid RAID5 parity stripe layout to the PAN_FS_CLIENT_LAYOUT_CREATE_FILE ioctl.\n", myname); } MPI_Abort(MPI_COMM_WORLD, 1); } if ((layout_visit_policy < PAN_FS_CLIENT_LAYOUT_VISIT__ROUND_ROBIN) || (layout_visit_policy > PAN_FS_CLIENT_LAYOUT_VISIT__ROUND_ROBIN_WITH_HASHED_OFFSET)) { FPRINTF(stderr, "%s: panfs_layout_visit_policy is not a valid value: %u.\n", myname, layout_visit_policy); MPI_Abort(MPI_COMM_WORLD, 1); } } if (layout_type == PAN_FS_CLIENT_LAYOUT_TYPE__RAID10) { if ((layout_stripe_unit == 0) || (layout_total_num_comps == 0)) { if(layout_stripe_unit == 0) { FPRINTF(stderr, "%s: MPI_Info does not contain the panfs_layout_stripe_unit hint which is necessary to specify a valid RAID10 layout to the PAN_FS_CLIENT_LAYOUT_CREATE_FILE ioctl.\n", myname); } if(layout_total_num_comps == 0) { FPRINTF(stderr, "%s: MPI_Info does not contain the panfs_layout_total_num_comps hint which is necessary to specify a valid RAID10 layout to the PAN_FS_CLIENT_LAYOUT_CREATE_FILE ioctl.\n", myname); } MPI_Abort(MPI_COMM_WORLD, 1); } if ((layout_visit_policy < PAN_FS_CLIENT_LAYOUT_VISIT__ROUND_ROBIN) || (layout_visit_policy > PAN_FS_CLIENT_LAYOUT_VISIT__ROUND_ROBIN_WITH_HASHED_OFFSET)) { FPRINTF(stderr, "%s: panfs_layout_visit_policy is not a valid value: %u.\n", myname, layout_visit_policy); MPI_Abort(MPI_COMM_WORLD, 1); } } /* Create the file via ioctl() or open(). ADIOI_PANFS_Open's caller * already optimizes performance by only calling this function with * ADIO_CREATE on rank 0. Therefore, we don't need to worry about * implementing that optimization here. */ if((layout_type == PAN_FS_CLIENT_LAYOUT_TYPE__RAID0) || (layout_type == PAN_FS_CLIENT_LAYOUT_TYPE__RAID1_5_PARITY_STRIPE) || (layout_type == PAN_FS_CLIENT_LAYOUT_TYPE__RAID10)) { pan_fs_client_layout_create_args_t file_create_args; int fd_dir; char* slash; struct stat stat_buf; int err; char *path; /* Check that the file does not exist before * trying to create it. The ioctl itself should * be able to handle this condition. Currently, * the ioctl will return successfully if the file * has been previously created. Filed bug 33862 * to track the problem. */ err = stat(fd->filename,&stat_buf); if((err == -1) && (errno != ENOENT)) { FPRINTF(stderr,"%s: Unexpected I/O Error calling stat() on PanFS file: %s.\n", myname, strerror(errno)); MPI_Abort(MPI_COMM_WORLD, 1); } else if (err == 0) { FPRINTF(stderr,"%s: Cannot create PanFS file with ioctl when file already exists.\n", myname); MPI_Abort(MPI_COMM_WORLD, 1); } else { /* (err == -1) && (errno == ENOENT) */ /* File does not exist */ path = ADIOI_Strdup(fd->filename); slash = strrchr(path, '/'); if (!slash) ADIOI_Strncpy(path, ".", 2); else { if (slash == path) *(path + 1) = '\0'; else *slash = '\0'; } /* create PanFS object */ bzero(&file_create_args,sizeof(pan_fs_client_layout_create_args_t)); /* open directory */ fd_dir = open(path, O_RDONLY); if (fd_dir < 0) { FPRINTF(stderr, "%s: I/O Error opening parent directory to create PanFS file using ioctl: %s.\n", myname, strerror(errno)); MPI_Abort(MPI_COMM_WORLD, 1); } else { char *file_name_ptr = fd->filename; slash = strrchr(fd->filename, '/'); if (slash) { file_name_ptr = slash + 1; } /* create file in the directory */ file_create_args.mode = perm; file_create_args.version = PAN_FS_CLIENT_LAYOUT_VERSION; file_create_args.flags = PAN_FS_CLIENT_LAYOUT_CREATE_F__NONE; ADIOI_Strncpy(file_create_args.filename, file_name_ptr, strlen(fd->filename)+1); file_create_args.layout.agg_type = layout_type; file_create_args.layout.layout_is_valid = 1; if(layout_type == PAN_FS_CLIENT_LAYOUT_TYPE__RAID1_5_PARITY_STRIPE) { file_create_args.layout.u.raid1_5_parity_stripe.total_num_comps = layout_total_num_comps; file_create_args.layout.u.raid1_5_parity_stripe.parity_stripe_width = layout_parity_stripe_width; file_create_args.layout.u.raid1_5_parity_stripe.parity_stripe_depth = layout_parity_stripe_depth; file_create_args.layout.u.raid1_5_parity_stripe.stripe_unit = layout_stripe_unit; file_create_args.layout.u.raid1_5_parity_stripe.layout_visit_policy = layout_visit_policy; } else if(layout_type == PAN_FS_CLIENT_LAYOUT_TYPE__RAID0) { file_create_args.layout.u.raid0.total_num_comps = layout_total_num_comps; file_create_args.layout.u.raid0.stripe_unit = layout_stripe_unit; } else if(layout_type == PAN_FS_CLIENT_LAYOUT_TYPE__RAID10) { file_create_args.layout.u.raid10.total_num_comps = layout_total_num_comps; file_create_args.layout.u.raid10.stripe_unit = layout_stripe_unit; file_create_args.layout.u.raid10.layout_visit_policy = layout_visit_policy; } err = ioctl(fd_dir, PAN_FS_CLIENT_LAYOUT_CREATE_FILE, &file_create_args); if (err < 0) { FPRINTF(stderr, "%s: I/O Error doing ioctl on parent directory to create PanFS file using ioctl: %s.\n", myname, strerror(errno)); MPI_Abort(MPI_COMM_WORLD, 1); } err = close(fd_dir); } ADIOI_Free(path); } } else { int create_fd = open(fd->filename,amode,perm); if(create_fd != -1) { close(create_fd); } else { FPRINTF(stderr, "%s: I/O Error creating PanFS file using open: %s.\n", myname, strerror(errno)); MPI_Abort(MPI_COMM_WORLD, 1); } } } if (fd->access_mode & ADIO_RDONLY) amode = amode | O_RDONLY; if (fd->access_mode & ADIO_WRONLY) amode = amode | O_WRONLY; if (fd->access_mode & ADIO_RDWR) amode = amode | O_RDWR; if (fd->access_mode & ADIO_EXCL) amode = amode | O_EXCL; value = (char *) ADIOI_Malloc((MPI_MAX_INFO_VAL+1)*sizeof(char)); ADIOI_Info_get(fd->info, "panfs_concurrent_write", MPI_MAX_INFO_VAL, value, &flag); if (flag) { unsigned long int concurrent_write = strtoul(value,NULL,10); if(concurrent_write == 1) { amode = amode | O_CONCURRENT_WRITE; } } ADIOI_Free(value); fd->fd_sys = open(fd->filename, amode, perm); fd->fd_direct = -1; if (fd->fd_sys != -1) { int rc; char temp_buffer[TEMP_BUFFER_SIZE]; pan_fs_client_layout_query_args_t file_query_args; bzero(&file_query_args,sizeof(pan_fs_client_layout_query_args_t)); file_query_args.version = PAN_FS_CLIENT_LAYOUT_VERSION; rc = ioctl(fd->fd_sys, PAN_FS_CLIENT_LAYOUT_QUERY_FILE, &file_query_args); if (rc < 0) { /* Error - set layout type to unknown */ ADIOI_Info_set(fd->info, "panfs_layout_type", "PAN_FS_CLIENT_LAYOUT_TYPE__INVALID"); } else { ADIOI_Snprintf(temp_buffer,TEMP_BUFFER_SIZE,"%u",file_query_args.layout.agg_type); ADIOI_Info_set(fd->info, "panfs_layout_type", temp_buffer); if (file_query_args.layout.layout_is_valid == 1) { switch (file_query_args.layout.agg_type) { case PAN_FS_CLIENT_LAYOUT_TYPE__RAID0: ADIOI_Snprintf(temp_buffer,TEMP_BUFFER_SIZE,"%u",file_query_args.layout.u.raid0.stripe_unit); ADIOI_Info_set(fd->info, "panfs_layout_stripe_unit", temp_buffer); ADIOI_Snprintf(temp_buffer,TEMP_BUFFER_SIZE,"%u",file_query_args.layout.u.raid0.total_num_comps); ADIOI_Info_set(fd->info, "panfs_layout_total_num_comps", temp_buffer); break; case PAN_FS_CLIENT_LAYOUT_TYPE__RAID1_5_PARITY_STRIPE: ADIOI_Snprintf(temp_buffer,TEMP_BUFFER_SIZE,"%u",file_query_args.layout.u.raid1_5_parity_stripe.stripe_unit); ADIOI_Info_set(fd->info, "panfs_layout_stripe_unit", temp_buffer); ADIOI_Snprintf(temp_buffer,TEMP_BUFFER_SIZE,"%u",file_query_args.layout.u.raid1_5_parity_stripe.parity_stripe_width); ADIOI_Info_set(fd->info, "panfs_layout_parity_stripe_width", temp_buffer); ADIOI_Snprintf(temp_buffer,TEMP_BUFFER_SIZE,"%u",file_query_args.layout.u.raid1_5_parity_stripe.parity_stripe_depth); ADIOI_Info_set(fd->info, "panfs_layout_parity_stripe_depth", temp_buffer); ADIOI_Snprintf(temp_buffer,TEMP_BUFFER_SIZE,"%u",file_query_args.layout.u.raid1_5_parity_stripe.total_num_comps); ADIOI_Info_set(fd->info, "panfs_layout_total_num_comps", temp_buffer); ADIOI_Snprintf(temp_buffer,TEMP_BUFFER_SIZE,"%u",file_query_args.layout.u.raid1_5_parity_stripe.layout_visit_policy); ADIOI_Info_set(fd->info, "panfs_layout_visit_policy", temp_buffer); break; case PAN_FS_CLIENT_LAYOUT_TYPE__RAID10: ADIOI_Snprintf(temp_buffer,TEMP_BUFFER_SIZE,"%u",file_query_args.layout.u.raid10.stripe_unit); ADIOI_Info_set(fd->info, "panfs_layout_stripe_unit", temp_buffer); ADIOI_Snprintf(temp_buffer,TEMP_BUFFER_SIZE,"%u",file_query_args.layout.u.raid10.total_num_comps); ADIOI_Info_set(fd->info, "panfs_layout_total_num_comps", temp_buffer); ADIOI_Snprintf(temp_buffer,TEMP_BUFFER_SIZE,"%u",file_query_args.layout.u.raid10.layout_visit_policy); ADIOI_Info_set(fd->info, "panfs_layout_visit_policy", temp_buffer); break; default: break; } } } } if ((fd->fd_sys != -1) && (fd->access_mode & ADIO_APPEND)) fd->fp_ind = fd->fp_sys_posn = lseek(fd->fd_sys, 0, SEEK_END); if (fd->fd_sys == -1) { if (errno == ENAMETOOLONG) *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_BAD_FILE, "**filenamelong", "**filenamelong %s %d", fd->filename, strlen(fd->filename)); else if (errno == ENOENT) *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_NO_SUCH_FILE, "**filenoexist", "**filenoexist %s", fd->filename); else if (errno == ENOTDIR || errno == ELOOP) *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_BAD_FILE, "**filenamedir", "**filenamedir %s", fd->filename); else if (errno == EACCES) { *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ACCESS, "**fileaccess", "**fileaccess %s", fd->filename ); } else if (errno == EROFS) { /* Read only file or file system and write access requested */ *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_READ_ONLY, "**ioneedrd", 0 ); } else { *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io", "**io %s", strerror(errno)); } } else *error_code = MPI_SUCCESS; }
void ADIOI_GEN_SetInfo(ADIO_File fd, MPI_Info users_info, int *error_code) { /* if fd->info is null, create a new info object. Initialize fd->info to default values. Initialize fd->hints to default values. Examine the info object passed by the user. If it contains values that ROMIO understands, override the default. */ MPI_Info info; char *value; int flag, nprocs=0, len; int ok_to_override_cb_nodes=0; static char myname[] = "ADIOI_GEN_SETINFO"; /* if we've already set up default hints and the user has not asked us to * process any hints (MPI_INFO_NULL), then we can short-circuit hint * processing */ if (fd->hints->initialized && fd->info == MPI_INFO_NULL) { *error_code = MPI_SUCCESS; return; } if (fd->info == MPI_INFO_NULL) MPI_Info_create(&(fd->info)); info = fd->info; MPI_Comm_size(fd->comm, &nprocs); /* Note that fd->hints is allocated at file open time; thus it is * not necessary to allocate it, or check for allocation, here. */ value = (char *) ADIOI_Malloc((MPI_MAX_INFO_VAL+1)*sizeof(char)); if (value == NULL) { *error_code = MPIO_Err_create_code(*error_code, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_OTHER, "**nomem2",0); return; } /* initialize info and hints to default values if they haven't been * previously initialized */ if (!fd->hints->initialized) { /* buffer size for collective I/O */ ADIOI_Info_set(info, "cb_buffer_size", ADIOI_CB_BUFFER_SIZE_DFLT); fd->hints->cb_buffer_size = atoi(ADIOI_CB_BUFFER_SIZE_DFLT); /* default is to let romio automatically decide when to use * collective buffering */ ADIOI_Info_set(info, "romio_cb_read", "automatic"); fd->hints->cb_read = ADIOI_HINT_AUTO; ADIOI_Info_set(info, "romio_cb_write", "automatic"); fd->hints->cb_write = ADIOI_HINT_AUTO; fd->hints->cb_config_list = NULL; /* number of processes that perform I/O in collective I/O */ ADIOI_Snprintf(value, MPI_MAX_INFO_VAL+1, "%d", nprocs); ADIOI_Info_set(info, "cb_nodes", value); fd->hints->cb_nodes = nprocs; /* hint indicating that no indep. I/O will be performed on this file */ ADIOI_Info_set(info, "romio_no_indep_rw", "false"); fd->hints->no_indep_rw = 0; /* hint instructing the use of persistent file realms */ ADIOI_Info_set(info, "romio_cb_pfr", "disable"); fd->hints->cb_pfr = ADIOI_HINT_DISABLE; /* hint guiding the assignment of persistent file realms */ ADIOI_Info_set(info, "romio_cb_fr_types", "aar"); fd->hints->cb_fr_type = ADIOI_FR_AAR; /* hint to align file realms with a certain byte value */ ADIOI_Info_set(info, "romio_cb_fr_alignment", "1"); fd->hints->cb_fr_alignment = 1; /* hint to set a threshold percentage for a datatype's size/extent at * which data sieving should be done in collective I/O */ ADIOI_Info_set(info, "romio_cb_ds_threshold", "0"); fd->hints->cb_ds_threshold = 0; /* hint to switch between point-to-point or all-to-all for two-phase */ ADIOI_Info_set(info, "romio_cb_alltoall", "automatic"); fd->hints->cb_alltoall = ADIOI_HINT_AUTO; /* deferred_open derived from no_indep_rw and cb_{read,write} */ fd->hints->deferred_open = 0; /* buffer size for data sieving in independent reads */ ADIOI_Info_set(info, "ind_rd_buffer_size", ADIOI_IND_RD_BUFFER_SIZE_DFLT); fd->hints->ind_rd_buffer_size = atoi(ADIOI_IND_RD_BUFFER_SIZE_DFLT); /* buffer size for data sieving in independent writes */ ADIOI_Info_set(info, "ind_wr_buffer_size", ADIOI_IND_WR_BUFFER_SIZE_DFLT); fd->hints->ind_wr_buffer_size = atoi(ADIOI_IND_WR_BUFFER_SIZE_DFLT); /* default is to let romio automatically decide when to use data * sieving */ ADIOI_Info_set(info, "romio_ds_read", "automatic"); fd->hints->ds_read = ADIOI_HINT_AUTO; ADIOI_Info_set(info, "romio_ds_write", "automatic"); fd->hints->ds_write = ADIOI_HINT_AUTO; /* still to do: tune this a bit for a variety of file systems. there's * no good default value so just leave it unset */ fd->hints->min_fdomain_size = 0; fd->hints->striping_unit = 0; fd->hints->initialized = 1; /* ADIO_Open sets up collective buffering arrays. If we are in this * path from say set_file_view, then we've don't want to adjust the * array: we'll get a segfault during collective i/o. We only want to * look at the users cb_nodes if it's open time */ ok_to_override_cb_nodes = 1; } /* add in user's info if supplied */ if (users_info != MPI_INFO_NULL) { ADIOI_Info_check_and_install_int(fd, users_info, "cb_buffer_size", &(fd->hints->cb_buffer_size), myname, error_code); /* aligning file realms to certain sizes (e.g. stripe sizes) * may benefit I/O performance */ ADIOI_Info_check_and_install_int(fd, users_info, "romio_cb_fr_alignment", &(fd->hints->cb_fr_alignment), myname, error_code); /* for collective I/O, try to be smarter about when to do data sieving * using a specific threshold for the datatype size/extent * (percentage 0-100%) */ ADIOI_Info_check_and_install_int(fd, users_info, "romio_cb_ds_threshold", &(fd->hints->cb_ds_threshold), myname, error_code); ADIOI_Info_check_and_install_enabled(fd, users_info, "romio_cb_alltoall", &(fd->hints->cb_alltoall), myname, error_code); /* new hints for enabling/disabling coll. buffering on * reads/writes */ ADIOI_Info_check_and_install_enabled(fd, users_info, "romio_cb_read", &(fd->hints->cb_read), myname, error_code); if (fd->hints->cb_read == ADIOI_HINT_DISABLE) { /* romio_cb_read overrides no_indep_rw */ ADIOI_Info_set(info, "romio_no_indep_rw", "false"); fd->hints->no_indep_rw = ADIOI_HINT_DISABLE; } ADIOI_Info_check_and_install_enabled(fd, users_info, "romio_cb_write", &(fd->hints->cb_write), myname, error_code); if (fd->hints->cb_write == ADIOI_HINT_DISABLE) { /* romio_cb_write overrides no_indep_rw */ ADIOI_Info_set(info, "romio_no_indep_rw", "false"); fd->hints->no_indep_rw = ADIOI_HINT_DISABLE; } /* enable/disable persistent file realms for collective I/O */ /* may want to check for no_indep_rdwr hint as well */ ADIOI_Info_check_and_install_enabled(fd, users_info, "romio_cb_pfr", &(fd->hints->cb_pfr), myname, error_code); /* file realm assignment types ADIOI_FR_AAR(0), ADIOI_FR_FSZ(-1), ADIOI_FR_USR_REALMS(-2), all others specify a regular fr size in bytes. probably not the best way... */ ADIOI_Info_check_and_install_int(fd, users_info, "romio_cb_fr_type", &(fd->hints->cb_fr_type), myname, error_code); /* Has the user indicated all I/O will be done collectively? */ ADIOI_Info_check_and_install_true(fd, users_info, "romio_no_indep_rw", &(fd->hints->no_indep_rw), myname, error_code); if (fd->hints->no_indep_rw == 1) { /* if 'no_indep_rw' set, also hint that we will do * collective buffering: if we aren't doing independent io, * then we have to do collective */ ADIOI_Info_set(info, "romio_cb_write", "enable"); ADIOI_Info_set(info, "romio_cb_read", "enable"); fd->hints->cb_read = 1; fd->hints->cb_write = 1; } /* new hints for enabling/disabling data sieving on * reads/writes */ ADIOI_Info_check_and_install_enabled(fd, users_info, "romio_ds_read", &(fd->hints->ds_read), myname, error_code); ADIOI_Info_check_and_install_enabled(fd, users_info, "romio_ds_write", &(fd->hints->ds_write), myname, error_code); if (ok_to_override_cb_nodes) { /* MPI_File_open path sets up some data structrues that don't * get resized in the MPI_File_set_view path, so ignore * cb_nodes in the set_view case */ ADIOI_Info_check_and_install_int(fd, users_info, "cb_nodes", &(fd->hints->cb_nodes), myname, error_code); if ((fd->hints->cb_nodes <= 0) || (fd->hints->cb_nodes > nprocs)) { /* can't ask for more aggregators than mpi processes, though it * might be interesting to think what such oversubscription * might mean... someday */ ADIOI_Snprintf(value, MPI_MAX_INFO_VAL+1, "%d", nprocs); ADIOI_Info_set(info, "cb_nodes", value); fd->hints->cb_nodes = nprocs; } } /* if (ok_to_override_cb_nodes) */ ADIOI_Info_check_and_install_int(fd, users_info, "ind_wr_buffer_size", &(fd->hints->ind_wr_buffer_size), myname, error_code); ADIOI_Info_check_and_install_int(fd, users_info, "ind_rd_buffer_size", &(fd->hints->ind_rd_buffer_size), myname, error_code); if (fd->hints->cb_config_list == NULL) { /* only set cb_config_list if it isn't already set. Note that * since we set it below, this ensures that the cb_config_list hint * will be set at file open time either by the user or to the * default */ /* if it has been set already, we ignore it the second time. * otherwise we would get an error if someone used the same info * value with a cb_config_list value in it in a couple of calls, * which would be irritating. */ ADIOI_Info_check_and_install_str(fd, users_info, "cb_config_list", &(fd->hints->cb_config_list), myname, error_code); } ADIOI_Info_check_and_install_int(fd, users_info, "romio_min_fdomain_size", &(fd->hints->min_fdomain_size), myname, error_code); /* Now we use striping unit in common code so we should process hints for it. */ ADIOI_Info_check_and_install_int(fd, users_info, "striping_unit", &(fd->hints->striping_unit), myname, error_code); } /* Begin hint post-processig: some hints take precidence over or conflict * with others, or aren't supported by some file systems */ /* handle cb_config_list default value here; avoids an extra * free/alloc and insures it is always set */ if (fd->hints->cb_config_list == NULL) { ADIOI_Info_set(info, "cb_config_list", ADIOI_CB_CONFIG_LIST_DFLT); len = (strlen(ADIOI_CB_CONFIG_LIST_DFLT)+1) * sizeof(char); fd->hints->cb_config_list = ADIOI_Malloc(len); if (fd->hints->cb_config_list == NULL) { ADIOI_Free(value); *error_code = MPIO_Err_create_code(*error_code, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_OTHER, "**nomem2",0); return; } ADIOI_Strncpy(fd->hints->cb_config_list, ADIOI_CB_CONFIG_LIST_DFLT, len); } /* deferred_open won't be set by callers, but if the user doesn't * explicitly disable collecitve buffering (two-phase) and does hint that * io w/o independent io is going on, we'll set this internal hint as a * convenience */ if ( ( (fd->hints->cb_read != ADIOI_HINT_DISABLE) \ && (fd->hints->cb_write != ADIOI_HINT_DISABLE)\ && fd->hints->no_indep_rw ) ) { fd->hints->deferred_open = 1; } else { /* setting romio_no_indep_rw enable and romio_cb_{read,write} * disable at the same time doesn't make sense. honor * romio_cb_{read,write} and force the no_indep_rw hint to * 'disable' */ ADIOI_Info_set(info, "romio_no_indep_rw", "false"); fd->hints->no_indep_rw = 0; fd->hints->deferred_open = 0; } if (ADIO_Feature(fd, ADIO_DATA_SIEVING_WRITES) == 0) { /* disable data sieving for fs that do not support file locking */ ADIOI_Info_get(info, "ind_wr_buffer_size", MPI_MAX_INFO_VAL, value, &flag); if (flag) { /* get rid of this value if it is set */ ADIOI_Info_delete(info, "ind_wr_buffer_size"); } /* note: leave ind_wr_buffer_size alone; used for other cases * as well. -- Rob Ross, 04/22/2003 */ ADIOI_Info_set(info, "romio_ds_write", "disable"); fd->hints->ds_write = ADIOI_HINT_DISABLE; } ADIOI_Free(value); *error_code = MPI_SUCCESS; }