1 /*
2  * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
3  *                         University Research and Technology
4  *                         Corporation.  All rights reserved.
5  * Copyright (c) 2004-2005 The University of Tennessee and The University
6  *                         of Tennessee Research Foundation.  All rights
7  *                         reserved.
8  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
9  *                         University of Stuttgart.  All rights reserved.
10  * Copyright (c) 2004-2005 The Regents of the University of California.
11  *                         All rights reserved.
12  * Copyright (c) 2015-2017 Research Organization for Information Science
13  *                         and Technology (RIST). All rights reserved.
14  * Copyright (c) 2016-2017 IBM Corporation. All rights reserved.
15  * $COPYRIGHT$
16  *
17  * Additional copyrights may follow
18  *
19  * $HEADER$
20  */
21 
22 #include "ompi_config.h"
23 
24 #include "ompi/communicator/communicator.h"
25 #include "ompi/info/info.h"
26 #include "ompi/file/file.h"
27 
28 #include "io_romio321.h"
29 
30 
31 int
mca_io_romio321_file_open(ompi_communicator_t * comm,const char * filename,int amode,opal_info_t * info,ompi_file_t * fh)32 mca_io_romio321_file_open (ompi_communicator_t *comm,
33                         const char *filename,
34                         int amode,
35                         opal_info_t *info,
36                         ompi_file_t *fh)
37 {
38     int ret;
39     mca_io_romio321_data_t *data;
40 
41 // An opal_info_t isn't a full ompi_info_t. so if we're using an MPI call
42 // below with an MPI_Info, we need to create an equivalent MPI_Info. This
43 // isn't ideal but it only happens a few places.
44     ompi_info_t *ompi_info;
45     ompi_info = OBJ_NEW(ompi_info_t);
46     if (!ompi_info) { return(MPI_ERR_NO_MEM); }
47     opal_info_t *opal_info = &(ompi_info->super);
48     opal_info_dup (info, &opal_info);
49 
50     data = (mca_io_romio321_data_t *) fh->f_io_selected_data;
51 //    OPAL_THREAD_LOCK (&mca_io_romio321_mutex);
52     ret = ROMIO_PREFIX(MPI_File_open)(comm, filename, amode, ompi_info,
53                                       &data->romio_fh);
54 //    OPAL_THREAD_UNLOCK (&mca_io_romio321_mutex);
55 
56     ompi_info_free(&ompi_info);
57     return ret;
58 }
59 
60 
61 int
mca_io_romio321_file_close(ompi_file_t * fh)62 mca_io_romio321_file_close (ompi_file_t *fh)
63 {
64     int ret;
65     mca_io_romio321_data_t *data;
66     int finalized;
67 
68     /* If we've already started MPI_Finalize by this point, then just
69        give up (because ROMIO's file close routine calls MPI_Barrier,
70        which we obviously can't do if we've started to MPI_Finalize).
71        The user didn't close the file, so they should expect
72        unexpected behavior. */
73     PMPI_Finalized(&finalized);
74     if (finalized) {
75         return OMPI_SUCCESS;
76     }
77 
78     /* Because ROMIO expects the MPI library to provide error handler
79      * management routines but it doesn't ever participate in
80      * MPI_File_close, we have to somehow inform the MPI library that
81      * we no longer hold a reference to any user defined error
82      * handler.  We do this by setting the errhandler at this point to
83      * MPI_ERRORS_RETURN. */
84     if (fh->error_handler != &ompi_mpi_errors_return.eh) {
85         OBJ_RELEASE(fh->error_handler);
86         fh->error_handler = &ompi_mpi_errors_return.eh;
87         OBJ_RETAIN(fh->error_handler);
88     }
89 
90     data = (mca_io_romio321_data_t *) fh->f_io_selected_data;
91 
92     OPAL_THREAD_LOCK (&mca_io_romio321_mutex);
93     ret = ROMIO_PREFIX(MPI_File_close) (&data->romio_fh);
94     OPAL_THREAD_UNLOCK (&mca_io_romio321_mutex);
95 
96     return ret;
97 }
98 
99 
100 int
mca_io_romio321_file_set_size(ompi_file_t * fh,MPI_Offset size)101 mca_io_romio321_file_set_size (ompi_file_t *fh,
102                             MPI_Offset size)
103 {
104     int ret;
105     mca_io_romio321_data_t *data;
106 
107     data = (mca_io_romio321_data_t *) fh->f_io_selected_data;
108     OPAL_THREAD_LOCK (&mca_io_romio321_mutex);
109     ret = ROMIO_PREFIX(MPI_File_set_size) (data->romio_fh, size);
110     OPAL_THREAD_UNLOCK (&mca_io_romio321_mutex);
111 
112     return ret;
113 }
114 
115 int
mca_io_romio321_file_preallocate(ompi_file_t * fh,MPI_Offset size)116 mca_io_romio321_file_preallocate (ompi_file_t *fh,
117                                MPI_Offset size)
118 {
119     int ret;
120     mca_io_romio321_data_t *data;
121 
122     data = (mca_io_romio321_data_t *) fh->f_io_selected_data;
123     OPAL_THREAD_LOCK (&mca_io_romio321_mutex);
124     ret = ROMIO_PREFIX(MPI_File_preallocate) (data->romio_fh, size);
125     OPAL_THREAD_UNLOCK (&mca_io_romio321_mutex);
126 
127     return ret;
128 }
129 
130 
131 int
mca_io_romio321_file_get_size(ompi_file_t * fh,MPI_Offset * size)132 mca_io_romio321_file_get_size (ompi_file_t *fh,
133                             MPI_Offset * size)
134 {
135     int ret;
136     mca_io_romio321_data_t *data;
137 
138     data = (mca_io_romio321_data_t *) fh->f_io_selected_data;
139     OPAL_THREAD_LOCK (&mca_io_romio321_mutex);
140     ret = ROMIO_PREFIX(MPI_File_get_size) (data->romio_fh, size);
141     OPAL_THREAD_UNLOCK (&mca_io_romio321_mutex);
142 
143     return ret;
144 }
145 
146 
147 int
mca_io_romio321_file_get_amode(ompi_file_t * fh,int * amode)148 mca_io_romio321_file_get_amode (ompi_file_t *fh,
149                              int *amode)
150 {
151     int ret;
152     mca_io_romio321_data_t *data;
153 
154     data = (mca_io_romio321_data_t *) fh->f_io_selected_data;
155     OPAL_THREAD_LOCK (&mca_io_romio321_mutex);
156     ret = ROMIO_PREFIX(MPI_File_get_amode) (data->romio_fh, amode);
157     OPAL_THREAD_UNLOCK (&mca_io_romio321_mutex);
158 
159     return ret;
160 }
161 
162 
163 int
mca_io_romio321_file_set_info(ompi_file_t * fh,opal_info_t * info)164 mca_io_romio321_file_set_info (ompi_file_t *fh,
165                             opal_info_t *info)
166 {
167     int ret;
168     mca_io_romio321_data_t *data;
169 
170 // An opal_info_t isn't a full ompi_info_t. so if we're using an MPI call
171 // below with an MPI_Info, we need to create an equivalent MPI_Info. This
172 // isn't ideal but it only happens a few places.
173     ompi_info_t *ompi_info;
174     ompi_info = OBJ_NEW(ompi_info_t);
175     if (!ompi_info) { return(MPI_ERR_NO_MEM); }
176     opal_info_t *opal_info = &(ompi_info->super);
177     opal_info_dup (info, &opal_info);
178 
179     data = (mca_io_romio321_data_t *) fh->f_io_selected_data;
180     OPAL_THREAD_LOCK (&mca_io_romio321_mutex);
181     ret = ROMIO_PREFIX(MPI_File_set_info) (data->romio_fh, ompi_info);
182     OPAL_THREAD_UNLOCK (&mca_io_romio321_mutex);
183 
184     ompi_info_free(&ompi_info);
185     return ret;
186 }
187 
188 
189 int
mca_io_romio321_file_get_info(ompi_file_t * fh,opal_info_t ** info_used)190 mca_io_romio321_file_get_info (ompi_file_t *fh,
191                             opal_info_t ** info_used)
192 {
193     int ret;
194     mca_io_romio321_data_t *data;
195 
196 // An opal_info_t isn't a full ompi_info_t. so if we're using an MPI call
197 // below with an MPI_Info, we need to create an equivalent MPI_Info. This
198 // isn't ideal but it only happens a few places.
199     ompi_info_t *ompi_info;
200     ompi_info = OBJ_NEW(ompi_info_t);
201     if (!ompi_info) { return(MPI_ERR_NO_MEM); }
202 
203     data = (mca_io_romio321_data_t *) fh->f_io_selected_data;
204     OPAL_THREAD_LOCK (&mca_io_romio321_mutex);
205     ret = ROMIO_PREFIX(MPI_File_get_info) (data->romio_fh, &ompi_info);
206     OPAL_THREAD_UNLOCK (&mca_io_romio321_mutex);
207 
208     opal_info_dup (&(ompi_info->super), info_used);
209     ompi_info_free(&ompi_info);
210     return ret;
211 }
212 
213 
214 int
mca_io_romio321_file_set_view(ompi_file_t * fh,MPI_Offset disp,struct ompi_datatype_t * etype,struct ompi_datatype_t * filetype,const char * datarep,opal_info_t * info)215 mca_io_romio321_file_set_view (ompi_file_t *fh,
216                             MPI_Offset disp,
217                             struct ompi_datatype_t *etype,
218                             struct ompi_datatype_t *filetype,
219                             const char *datarep,
220                             opal_info_t *info)
221 {
222     int ret;
223     mca_io_romio321_data_t *data;
224 
225 // An opal_info_t isn't a full ompi_info_t. so if we're using an MPI call
226 // below with an MPI_Info, we need to create an equivalent MPI_Info. This
227 // isn't ideal but it only happens a few places.
228     ompi_info_t *ompi_info;
229     ompi_info = OBJ_NEW(ompi_info_t);
230     if (!ompi_info) { return(MPI_ERR_NO_MEM); }
231     opal_info_t *opal_info = &(ompi_info->super);
232     opal_info_dup (info, &opal_info);
233 
234     data = (mca_io_romio321_data_t *) fh->f_io_selected_data;
235     OPAL_THREAD_LOCK (&mca_io_romio321_mutex);
236     ret =
237         ROMIO_PREFIX(MPI_File_set_view) (data->romio_fh, disp, etype, filetype,
238                                         datarep, ompi_info);
239     OPAL_THREAD_UNLOCK (&mca_io_romio321_mutex);
240 
241     ompi_info_free(&ompi_info);
242     return ret;
243 }
244 
245 
246 int
mca_io_romio321_file_get_view(ompi_file_t * fh,MPI_Offset * disp,struct ompi_datatype_t ** etype,struct ompi_datatype_t ** filetype,char * datarep)247 mca_io_romio321_file_get_view (ompi_file_t *fh,
248                             MPI_Offset * disp,
249                             struct ompi_datatype_t ** etype,
250                             struct ompi_datatype_t ** filetype,
251                             char *datarep)
252 {
253     int ret;
254     mca_io_romio321_data_t *data;
255 
256     data = (mca_io_romio321_data_t *) fh->f_io_selected_data;
257     OPAL_THREAD_LOCK (&mca_io_romio321_mutex);
258     ret =
259         ROMIO_PREFIX(MPI_File_get_view) (data->romio_fh, disp, etype, filetype,
260                                         datarep);
261     OPAL_THREAD_UNLOCK (&mca_io_romio321_mutex);
262 
263     return ret;
264 
265 }
266 
267 
268 int
mca_io_romio321_file_get_type_extent(ompi_file_t * fh,struct ompi_datatype_t * datatype,MPI_Aint * extent)269 mca_io_romio321_file_get_type_extent (ompi_file_t *fh,
270                                    struct ompi_datatype_t *datatype,
271                                    MPI_Aint * extent)
272 {
273     int ret;
274     mca_io_romio321_data_t *data;
275 
276     data = (mca_io_romio321_data_t *) fh->f_io_selected_data;
277     OPAL_THREAD_LOCK (&mca_io_romio321_mutex);
278     ret =
279         ROMIO_PREFIX(MPI_File_get_type_extent) (data->romio_fh, datatype, extent);
280     OPAL_THREAD_UNLOCK (&mca_io_romio321_mutex);
281 
282     return ret;
283 }
284 
285 
286 int
mca_io_romio321_file_set_atomicity(ompi_file_t * fh,int flag)287 mca_io_romio321_file_set_atomicity (ompi_file_t *fh,
288                                  int flag)
289 {
290     int ret;
291     mca_io_romio321_data_t *data;
292 
293     data = (mca_io_romio321_data_t *) fh->f_io_selected_data;
294     OPAL_THREAD_LOCK (&mca_io_romio321_mutex);
295     ret = ROMIO_PREFIX(MPI_File_set_atomicity) (data->romio_fh, flag);
296     OPAL_THREAD_UNLOCK (&mca_io_romio321_mutex);
297 
298     return ret;
299 }
300 
301 int
mca_io_romio321_file_get_atomicity(ompi_file_t * fh,int * flag)302 mca_io_romio321_file_get_atomicity (ompi_file_t *fh,
303                                  int *flag)
304 {
305     int ret;
306     mca_io_romio321_data_t *data;
307 
308     data = (mca_io_romio321_data_t *) fh->f_io_selected_data;
309     OPAL_THREAD_LOCK (&mca_io_romio321_mutex);
310     ret = ROMIO_PREFIX(MPI_File_get_atomicity) (data->romio_fh, flag);
311     OPAL_THREAD_UNLOCK (&mca_io_romio321_mutex);
312 
313     return ret;
314 }
315 
316 int
mca_io_romio321_file_sync(ompi_file_t * fh)317 mca_io_romio321_file_sync (ompi_file_t *fh)
318 {
319     int ret;
320     mca_io_romio321_data_t *data;
321 
322     data = (mca_io_romio321_data_t *) fh->f_io_selected_data;
323     OPAL_THREAD_LOCK (&mca_io_romio321_mutex);
324     ret = ROMIO_PREFIX(MPI_File_sync) (data->romio_fh);
325     OPAL_THREAD_UNLOCK (&mca_io_romio321_mutex);
326 
327     return ret;
328 }
329 
330 
331 int
mca_io_romio321_file_seek_shared(ompi_file_t * fh,MPI_Offset offset,int whence)332 mca_io_romio321_file_seek_shared (ompi_file_t *fh,
333                                MPI_Offset offset,
334                                int whence)
335 {
336     int ret;
337     mca_io_romio321_data_t *data;
338 
339     data = (mca_io_romio321_data_t *) fh->f_io_selected_data;
340     OPAL_THREAD_LOCK (&mca_io_romio321_mutex);
341     ret = ROMIO_PREFIX(MPI_File_seek_shared) (data->romio_fh, offset, whence);
342     OPAL_THREAD_UNLOCK (&mca_io_romio321_mutex);
343 
344     return ret;
345 }
346 
347 
348 int
mca_io_romio321_file_get_position_shared(ompi_file_t * fh,MPI_Offset * offset)349 mca_io_romio321_file_get_position_shared (ompi_file_t *fh,
350                                        MPI_Offset * offset)
351 {
352     int ret;
353     mca_io_romio321_data_t *data;
354 
355     data = (mca_io_romio321_data_t *) fh->f_io_selected_data;
356     OPAL_THREAD_LOCK (&mca_io_romio321_mutex);
357     ret = ROMIO_PREFIX(MPI_File_get_position_shared) (data->romio_fh, offset);
358     OPAL_THREAD_UNLOCK (&mca_io_romio321_mutex);
359 
360     return ret;
361 }
362 
363 
364 int
mca_io_romio321_file_seek(ompi_file_t * fh,MPI_Offset offset,int whence)365 mca_io_romio321_file_seek (ompi_file_t *fh,
366                         MPI_Offset offset,
367                         int whence)
368 {
369     int ret;
370     mca_io_romio321_data_t *data;
371 
372     data = (mca_io_romio321_data_t *) fh->f_io_selected_data;
373     OPAL_THREAD_LOCK (&mca_io_romio321_mutex);
374     ret = ROMIO_PREFIX(MPI_File_seek) (data->romio_fh, offset, whence);
375     OPAL_THREAD_UNLOCK (&mca_io_romio321_mutex);
376 
377     return ret;
378 }
379 
380 
381 int
mca_io_romio321_file_get_position(ompi_file_t * fh,MPI_Offset * offset)382 mca_io_romio321_file_get_position (ompi_file_t *fh,
383                                 MPI_Offset * offset)
384 {
385     int ret;
386     mca_io_romio321_data_t *data;
387 
388     data = (mca_io_romio321_data_t *) fh->f_io_selected_data;
389     OPAL_THREAD_LOCK (&mca_io_romio321_mutex);
390     ret = ROMIO_PREFIX(MPI_File_get_position) (data->romio_fh, offset);
391     OPAL_THREAD_UNLOCK (&mca_io_romio321_mutex);
392 
393     return ret;
394 }
395 
396 
397 int
mca_io_romio321_file_get_byte_offset(ompi_file_t * fh,MPI_Offset offset,MPI_Offset * disp)398 mca_io_romio321_file_get_byte_offset (ompi_file_t *fh,
399                                    MPI_Offset offset,
400                                    MPI_Offset * disp)
401 {
402     int ret;
403     mca_io_romio321_data_t *data;
404 
405     data = (mca_io_romio321_data_t *) fh->f_io_selected_data;
406     OPAL_THREAD_LOCK (&mca_io_romio321_mutex);
407     ret = ROMIO_PREFIX(MPI_File_get_byte_offset) (data->romio_fh, offset, disp);
408     OPAL_THREAD_UNLOCK (&mca_io_romio321_mutex);
409 
410     return ret;
411 }
412