open.c 6.33 KB
Newer Older
1
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/* 
 *
 *   Copyright (C) 1997 University of Chicago. 
 *   See COPYRIGHT notice 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 */
19
20
#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")));
21
22
23
24
25
26
27
#endif

/* Include mapping from MPI->PMPI */
#define MPIO_BUILD_PROFILING
#include "mpioprof.h"
#endif

28
29
30
31
/* for user-definde reduce operator */
#include "adio_extern.h"


32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
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
@*/
48
int MPI_File_open(MPI_Comm comm, ROMIO_CONST char *filename, int amode,
49
50
                  MPI_Info info, MPI_File *fh)
{
51
    int error_code = MPI_SUCCESS, file_system, flag, tmp_amode=0, rank;
52
    char *tmp;
53
    MPI_Comm dupcomm = MPI_COMM_NULL;
54
55
56
57
58
59
60
61
    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 */

62
    MPIU_THREAD_CS_ENTER(ALLFUNC,);
63
64

    /* --BEGIN ERROR HANDLING-- */
65
    MPIO_CHECK_COMM(comm, myname, error_code);
66
    MPIO_CHECK_INFO_ALL(info, error_code, comm);
67
68
    /* --END ERROR HANDLING-- */

69
    error_code = MPI_Comm_test_inter(comm, &flag);
70
    /* --BEGIN ERROR HANDLING-- */
71
    if (error_code || flag)
72
    {
73
	error_code = MPIO_Err_create_code(error_code, MPIR_ERR_RECOVERABLE,
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
					  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 */
108
109
    MPIR_MPIOInit(&error_code);
    if (error_code != MPI_SUCCESS) goto fn_fail;
110

111
112
113
114
115
116
/* 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 */
117
118
119
120
    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,
121
			myname, __LINE__, MPI_ERR_NOT_SAME,
122
123
124
125
126
			"**fileamodediff", 0);
	goto fn_fail;
    }
    /* --END ERROR HANDLING-- */

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
    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-- */

163
164
165
166
167
168
169
170
171
172
173
174
175
    /* 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;
    }

176
177
178
    /* 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. */
179
180
    if ((error_code == MPI_SUCCESS) && 
		    ADIO_Feature((*fh), ADIO_SHARED_FP)) {
181
	MPI_Comm_rank(dupcomm, &rank);
182
183
184
	ADIOI_Shfp_fname(*fh, rank, &error_code);
	if (error_code != MPI_SUCCESS)
	    goto fn_fail;
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200

        /* 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:
201
    MPIU_THREAD_CS_EXIT(ALLFUNC,);
202
203
204
    return error_code;
fn_fail:
    /* --BEGIN ERROR HANDLING-- */
205
    if (dupcomm != MPI_COMM_NULL) MPI_Comm_free(&dupcomm);
206
207
208
209
    error_code = MPIO_Err_return_file(MPI_FILE_NULL, error_code);
    goto fn_exit;
    /* --END ERROR HANDLING-- */
}