1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
|
/*
* Copyright (C) by Argonne National Laboratory
* See COPYRIGHT in top-level directory
*/
#include "mpioimpl.h"
#ifdef HAVE_WEAK_SYMBOLS
#if defined(HAVE_PRAGMA_WEAK)
#pragma weak MPI_File_open = PMPI_File_open
#elif defined(HAVE_PRAGMA_HP_SEC_DEF)
#pragma _HP_SECONDARY_DEF PMPI_File_open MPI_File_open
#elif defined(HAVE_PRAGMA_CRI_DUP)
#pragma _CRI duplicate MPI_File_open as PMPI_File_open
/* end of weak pragmas */
#elif defined(HAVE_WEAK_ATTRIBUTE)
int MPI_File_open(MPI_Comm comm, const char *filename, int amode, MPI_Info info, MPI_File * fh)
__attribute__ ((weak, alias("PMPI_File_open")));
#endif
/* Include mapping from MPI->PMPI */
#define MPIO_BUILD_PROFILING
#include "mpioprof.h"
#endif
/* for user-definde reduce operator */
#include "adio_extern.h"
extern int ADIO_Init_keyval;
/*@
MPI_File_open - Opens a file
Input Parameters:
. comm - communicator (handle)
. filename - name of file to open (string)
. amode - file access mode (integer)
. info - info object (handle)
Output Parameters:
. fh - file handle (handle)
.N fortran
@*/
int MPI_File_open(MPI_Comm comm, ROMIO_CONST char *filename, int amode,
MPI_Info info, MPI_File * fh)
{
int error_code = MPI_SUCCESS, file_system, flag, tmp_amode = 0, rank;
char *tmp;
MPI_Comm dupcomm = MPI_COMM_NULL;
ADIOI_Fns *fsops;
static char myname[] = "MPI_FILE_OPEN";
#ifdef MPI_hpux
int fl_xmpi;
HPMP_IO_OPEN_START(fl_xmpi, comm);
#endif /* MPI_hpux */
ROMIO_THREAD_CS_ENTER();
/* --BEGIN ERROR HANDLING-- */
MPIO_CHECK_COMM(comm, myname, error_code);
MPIO_CHECK_INFO_ALL(info, error_code, comm);
/* --END ERROR HANDLING-- */
error_code = MPI_Comm_test_inter(comm, &flag);
/* --BEGIN ERROR HANDLING-- */
if (error_code || flag) {
error_code = MPIO_Err_create_code(error_code, MPIR_ERR_RECOVERABLE,
myname, __LINE__, MPI_ERR_COMM, "**commnotintra", 0);
goto fn_fail;
}
if (((amode & MPI_MODE_RDONLY) ? 1 : 0) + ((amode & MPI_MODE_RDWR) ? 1 : 0) +
((amode & MPI_MODE_WRONLY) ? 1 : 0) != 1) {
error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
myname, __LINE__, MPI_ERR_AMODE, "**fileamodeone", 0);
goto fn_fail;
}
if ((amode & MPI_MODE_RDONLY) && ((amode & MPI_MODE_CREATE) || (amode & MPI_MODE_EXCL))) {
error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
myname, __LINE__, MPI_ERR_AMODE, "**fileamoderead", 0);
goto fn_fail;
}
if ((amode & MPI_MODE_RDWR) && (amode & MPI_MODE_SEQUENTIAL)) {
error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
myname, __LINE__, MPI_ERR_AMODE, "**fileamodeseq", 0);
goto fn_fail;
}
MPI_Comm_dup(comm, &dupcomm);
/* check if ADIO has been initialized. If not, initialize it */
MPIR_MPIOInit(&error_code);
if (error_code != MPI_SUCCESS)
goto fn_fail;
/* check if amode is the same on all processes: at first glance, one might try
* to use a built-in operator like MPI_BAND, but we need every mpi process to
* agree the amode was not the same. Consider process A with
* MPI_MODE_CREATE|MPI_MODE_RDWR, and B with MPI_MODE_RDWR: MPI_BAND yields
* MPI_MODE_RDWR. A determines amodes are different, but B proceeds having not
* detected an error */
MPI_Allreduce(&amode, &tmp_amode, 1, MPI_INT, ADIO_same_amode, dupcomm);
if (tmp_amode == ADIO_AMODE_NOMATCH) {
error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
myname, __LINE__, MPI_ERR_NOT_SAME, "**fileamodediff", 0);
goto fn_fail;
}
/* --END ERROR HANDLING-- */
file_system = -1;
/* resolve file system type from file name; this is a collective call */
ADIO_ResolveFileType(dupcomm, filename, &file_system, &fsops, &error_code);
/* --BEGIN ERROR HANDLING-- */
if (error_code != MPI_SUCCESS) {
/* ADIO_ResolveFileType() will print as informative a message as it
* possibly can or call MPIO_Err_setmsg. We just need to propagate
* the error up.
*/
goto fn_fail;
}
/* --END ERROR HANDLING-- */
/* strip off prefix if there is one, but only skip prefixes
* if they are greater than length one to allow for windows
* drive specifications (e.g. c:\...) */
tmp = strchr(filename, ':');
if (tmp > filename + 1) {
filename = tmp + 1;
}
/* use default values for disp, etype, filetype */
*fh = ADIO_Open(comm, dupcomm, filename, file_system, fsops, amode, 0,
MPI_BYTE, MPI_BYTE, info, ADIO_PERM_NULL, &error_code);
/* --BEGIN ERROR HANDLING-- */
if (error_code != MPI_SUCCESS) {
goto fn_fail;
}
/* --END ERROR HANDLING-- */
/* if MPI_MODE_SEQUENTIAL requested, file systems cannot do explicit offset
* or independent file pointer accesses, leaving not much else aside from
* shared file pointer accesses. */
if (!ADIO_Feature((*fh), ADIO_SHARED_FP) && (amode & MPI_MODE_SEQUENTIAL)) {
error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
myname, __LINE__,
MPI_ERR_UNSUPPORTED_OPERATION, "**iosequnsupported", 0);
ADIO_Close(*fh, &error_code);
goto fn_fail;
}
/* determine name of file that will hold the shared file pointer */
/* can't support shared file pointers on a file system that doesn't
* support file locking. */
if ((error_code == MPI_SUCCESS) && ADIO_Feature((*fh), ADIO_SHARED_FP)) {
MPI_Comm_rank(dupcomm, &rank);
ADIOI_Shfp_fname(*fh, rank, &error_code);
if (error_code != MPI_SUCCESS)
goto fn_fail;
/* if MPI_MODE_APPEND, set the shared file pointer to end of file.
* indiv. file pointer already set to end of file in ADIO_Open.
* Here file view is just bytes. */
if ((*fh)->access_mode & MPI_MODE_APPEND) {
if (rank == (*fh)->hints->ranklist[0]) /* only one person need set the sharedfp */
ADIO_Set_shared_fp(*fh, (*fh)->fp_ind, &error_code);
MPI_Barrier(dupcomm);
}
}
#ifdef MPI_hpux
HPMP_IO_OPEN_END(fl_xmpi, *fh, comm);
#endif /* MPI_hpux */
fn_exit:
ROMIO_THREAD_CS_EXIT();
return error_code;
fn_fail:
/* --BEGIN ERROR HANDLING-- */
if (dupcomm != MPI_COMM_NULL)
MPI_Comm_free(&dupcomm);
error_code = MPIO_Err_return_file(MPI_FILE_NULL, error_code);
goto fn_exit;
/* --END ERROR HANDLING-- */
}
|