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