00001
00002
00003
00004
00005
00006
00007
00008 #include "adio.h"
00009 #include "adio_extern.h"
00010 #include "adio_cb_config_list.h"
00011
00012 #include "mpio.h"
00013
00014 static int is_aggregator(int rank, ADIO_File fd);
00015 static int uses_generic_read(ADIO_File fd);
00016 static int uses_generic_write(ADIO_File fd);
00017 static int build_cb_config_list(ADIO_File fd,
00018 MPI_Comm orig_comm, MPI_Comm comm,
00019 int rank, int procs, int *error_code);
00020
00021 MPI_File ADIO_Open(MPI_Comm orig_comm,
00022 MPI_Comm comm, char *filename, int file_system,
00023 ADIOI_Fns *ops,
00024 int access_mode, ADIO_Offset disp, MPI_Datatype etype,
00025 MPI_Datatype filetype,
00026 MPI_Info info, int perm, int *error_code)
00027 {
00028 MPI_File mpi_fh;
00029 ADIO_File fd;
00030 int err, rank, procs;
00031 static char myname[] = "ADIO_OPEN";
00032 int max_error_code;
00033 MPI_Info dupinfo;
00034 MPI_Comm aggregator_comm = MPI_COMM_NULL;
00035
00036 *error_code = MPI_SUCCESS;
00037
00038
00039 mpi_fh = MPIO_File_create(sizeof(struct ADIOI_FileD));
00040 if (mpi_fh == MPI_FILE_NULL) {
00041 }
00042 fd = MPIO_File_resolve(mpi_fh);
00043
00044 fd->cookie = ADIOI_FILE_COOKIE;
00045 fd->fp_ind = disp;
00046 fd->fp_sys_posn = 0;
00047 fd->comm = comm;
00048 fd->filename = ADIOI_Strdup(filename);
00049 fd->file_system = file_system;
00050 fd->fs_ptr = NULL;
00051
00052 fd->fns = ops;
00053
00054 fd->disp = disp;
00055 fd->split_coll_count = 0;
00056 fd->shared_fp_fd = ADIO_FILE_NULL;
00057 fd->atomicity = 0;
00058 fd->etype = etype;
00059 fd->filetype = filetype;
00060 fd->etype_size = 1;
00061
00062 fd->file_realm_st_offs = NULL;
00063 fd->file_realm_types = NULL;
00064
00065 fd->perm = perm;
00066
00067 fd->async_count = 0;
00068
00069 fd->fortran_handle = -1;
00070
00071 fd->err_handler = CtvAccess(ADIOI_DFLT_ERR_HANDLER);
00072
00073 MPI_Comm_rank(comm, &rank);
00074 MPI_Comm_size(comm, &procs);
00075
00076 fd->hints = (ADIOI_Hints *)ADIOI_Calloc(1, sizeof(struct ADIOI_Hints_struct));
00077 if (fd->hints == NULL) {
00078
00079 }
00080 fd->hints->cb_config_list = NULL;
00081 fd->hints->ranklist = NULL;
00082 fd->hints->initialized = 0;
00083 fd->info = MPI_INFO_NULL;
00084
00085 ADIOI_incorporate_system_hints(info, CtvAccess(ADIOI_syshints), &dupinfo);
00086 ADIO_SetInfo(fd, dupinfo, &err);
00087 if (dupinfo != MPI_INFO_NULL) {
00088 *error_code = MPI_Info_free(&dupinfo);
00089 if (*error_code != MPI_SUCCESS)
00090 goto fn_exit;
00091 }
00092
00093
00094
00095
00096
00097
00098
00099 if (fd->hints->deferred_open &&
00100 !(uses_generic_read(fd) \
00101 && uses_generic_write(fd))) {
00102 fd->hints->deferred_open = 0;
00103 }
00104 if (ADIO_Feature(fd, ADIO_SCALABLE_OPEN))
00105
00106
00107 fd->hints->deferred_open = 0;
00108
00109
00110
00111
00112 if (fd->hints->ranklist == NULL) {
00113 build_cb_config_list(fd, orig_comm, comm, rank, procs, error_code);
00114 if (*error_code != MPI_SUCCESS)
00115 goto fn_exit;
00116 }
00117
00118
00119
00120
00121
00122 fd->agg_comm = MPI_COMM_NULL;
00123 fd->is_open = 0;
00124 fd->my_cb_nodes_index = -2;
00125 fd->is_agg = is_aggregator(rank, fd);
00126 if (fd->hints->deferred_open) {
00127
00128
00129
00130
00131 if (fd->is_agg) {
00132 MPI_Comm_split(fd->comm, 1, 0, &aggregator_comm);
00133 fd->agg_comm = aggregator_comm;
00134 } else {
00135 MPI_Comm_split(fd->comm, MPI_UNDEFINED, 0, &aggregator_comm);
00136 fd->agg_comm = aggregator_comm;
00137 }
00138
00139 }
00140
00141
00142
00143
00144
00145
00146
00147 ADIOI_OpenColl(fd, rank, access_mode, error_code);
00148
00149 fn_exit:
00150 MPI_Allreduce(error_code, &max_error_code, 1, MPI_INT, MPI_MAX, comm);
00151 if (max_error_code != MPI_SUCCESS) {
00152
00153
00154 if (*error_code == MPI_SUCCESS) {
00155
00156
00157
00158 if (fd->hints->deferred_open) {
00159 if (fd->agg_comm != MPI_COMM_NULL) {
00160 (*(fd->fns->ADIOI_xxx_Close))(fd, error_code);
00161 }
00162 }
00163 else {
00164 (*(fd->fns->ADIOI_xxx_Close))(fd, error_code);
00165 }
00166 }
00167 if (fd->filename) ADIOI_Free(fd->filename);
00168 if (fd->hints->ranklist) ADIOI_Free(fd->hints->ranklist);
00169 if (fd->hints->cb_config_list) ADIOI_Free(fd->hints->cb_config_list);
00170 if (fd->hints) ADIOI_Free(fd->hints);
00171 if (fd->info != MPI_INFO_NULL) MPI_Info_free(&(fd->info));
00172 ADIOI_Free(fd);
00173 fd = ADIO_FILE_NULL;
00174 if (*error_code == MPI_SUCCESS)
00175 {
00176 *error_code = MPIO_Err_create_code(MPI_SUCCESS,
00177 MPIR_ERR_RECOVERABLE, myname,
00178 __LINE__, MPI_ERR_IO,
00179 "**oremote_fail", 0);
00180 }
00181 }
00182
00183 return fd;
00184 }
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194 int is_aggregator(int rank, ADIO_File fd ) {
00195 int i;
00196
00197 if (fd->my_cb_nodes_index == -2) {
00198 for (i=0; i< fd->hints->cb_nodes; i++ ) {
00199 if ( rank == fd->hints->ranklist[i] ) {
00200 fd->my_cb_nodes_index = i;
00201 return 1;
00202 }
00203 }
00204 fd->my_cb_nodes_index = -1;
00205 }
00206 else if (fd->my_cb_nodes_index != -1)
00207 return 1;
00208
00209 return 0;
00210 }
00211
00212
00213
00214
00215 static int uses_generic_read(ADIO_File fd)
00216 {
00217 ADIOI_Fns *fns = fd->fns;
00218 if (fns->ADIOI_xxx_ReadStridedColl == ADIOI_GEN_ReadStridedColl ||
00219 fd->file_system == ADIO_TESTFS )
00220 {
00221 return 1;
00222 }
00223 return 0;
00224 }
00225
00226 static int uses_generic_write(ADIO_File fd)
00227 {
00228 ADIOI_Fns *fns = fd->fns;
00229 if (fns->ADIOI_xxx_WriteStridedColl == ADIOI_GEN_WriteStridedColl ||
00230 fd->file_system == ADIO_TESTFS )
00231 {
00232 return 1;
00233 }
00234 return 0;
00235 }
00236
00237 static int build_cb_config_list(ADIO_File fd,
00238 MPI_Comm orig_comm, MPI_Comm comm,
00239 int rank, int procs, int *error_code)
00240 {
00241 ADIO_cb_name_array array;
00242 int *tmp_ranklist;
00243 int rank_ct;
00244 char *value;
00245 static char myname[] = "ADIO_OPEN cb_config_list";
00246
00247
00248
00249
00250
00251 ADIOI_cb_gather_name_array(orig_comm, comm, &array);
00252
00253
00254 if (rank == 0) {
00255 tmp_ranklist = (int *) ADIOI_Malloc(sizeof(int) * procs);
00256 if (tmp_ranklist == NULL) {
00257
00258 }
00259
00260 rank_ct = ADIOI_cb_config_list_parse(fd->hints->cb_config_list,
00261 array, tmp_ranklist,
00262 fd->hints->cb_nodes);
00263
00264
00265 if (rank_ct > 0) {
00266 fd->hints->ranklist = (int *) ADIOI_Malloc(sizeof(int) * rank_ct);
00267 memcpy(fd->hints->ranklist, tmp_ranklist, sizeof(int) * rank_ct);
00268 }
00269 ADIOI_Free(tmp_ranklist);
00270 fd->hints->cb_nodes = rank_ct;
00271
00272 value = (char *) ADIOI_Malloc((MPI_MAX_INFO_VAL+1)*sizeof(char));
00273 ADIOI_Snprintf(value, MPI_MAX_INFO_VAL+1, "%d", rank_ct);
00274 ADIOI_Info_set(fd->info, "cb_nodes", value);
00275 ADIOI_Free(value);
00276 }
00277
00278 ADIOI_cb_bcast_rank_map(fd);
00279 if (fd->hints->cb_nodes <= 0) {
00280 *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
00281 myname, __LINE__, MPI_ERR_IO,
00282 "**ioagnomatch", 0);
00283 fd = ADIO_FILE_NULL;
00284 }
00285 return 0;
00286 }
00287
00288
00289
00290