1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  * Copyright by The HDF Group.                                               *
3  * Copyright by the Board of Trustees of the University of Illinois.         *
4  * All rights reserved.                                                      *
5  *                                                                           *
6  * This file is part of HDF5.  The full HDF5 copyright notice, including     *
7  * terms governing use, modification, and redistribution, is contained in    *
8  * the COPYING file, which can be found at the root of the source code       *
9  * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases.  *
10  * If you do not have access to either file, you may request a copy from     *
11  * help@hdfgroup.org.                                                        *
12  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13 
14 /*-------------------------------------------------------------------------
15  *
16  * Created:             H5Fmpi.c
17  *                      Jan 10 2008
18  *                      Quincey Koziol <koziol@hdfgroup.org>
19  *
20  * Purpose:             MPI-related routines.
21  *
22  *-------------------------------------------------------------------------
23  */
24 
25 /****************/
26 /* Module Setup */
27 /****************/
28 
29 #include "H5Fmodule.h"          /* This source code file is part of the H5F module */
30 
31 
32 /***********/
33 /* Headers */
34 /***********/
35 #include "H5private.h"		/* Generic Functions			*/
36 #include "H5Eprivate.h"		/* Error handling		  	*/
37 #include "H5Fpkg.h"             /* File access				*/
38 #include "H5FDprivate.h"	/* File drivers				*/
39 #include "H5Iprivate.h"		/* IDs			  		*/
40 
41 
42 /****************/
43 /* Local Macros */
44 /****************/
45 
46 
47 /******************/
48 /* Local Typedefs */
49 /******************/
50 
51 
52 /********************/
53 /* Package Typedefs */
54 /********************/
55 
56 
57 /********************/
58 /* Local Prototypes */
59 /********************/
60 
61 
62 /*********************/
63 /* Package Variables */
64 /*********************/
65 
66 
67 /*****************************/
68 /* Library Private Variables */
69 /*****************************/
70 
71 
72 /*******************/
73 /* Local Variables */
74 /*******************/
75 
76 
77 #ifdef H5_HAVE_PARALLEL
78 
79 /*-------------------------------------------------------------------------
80  * Function:    H5F_get_mpi_handle
81  *
82  * Purpose:     Retrieves MPI File handle.
83  *
84  * Return:      Success:        The size (positive)
85  *              Failure:        Negative
86  *
87  *-------------------------------------------------------------------------
88  */
89 herr_t
H5F_get_mpi_handle(const H5F_t * f,MPI_File ** f_handle)90 H5F_get_mpi_handle(const H5F_t *f, MPI_File **f_handle)
91 {
92     herr_t ret_value = SUCCEED;
93     hid_t fapl = -1;
94 
95     FUNC_ENTER_NOAPI(FAIL)
96 
97     assert(f && f->shared);
98 
99     /* Dispatch to driver */
100     if ((ret_value = H5FD_get_vfd_handle(f->shared->lf, fapl, (void **)f_handle)) < 0)
101         HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get mpi file handle")
102 
103 done:
104     FUNC_LEAVE_NOAPI(ret_value)
105 } /* end H5F_get_mpi_handle() */
106 
107 
108 /*-------------------------------------------------------------------------
109  * Function:	H5F_mpi_get_rank
110  *
111  * Purpose:	Retrieves the rank of an MPI process.
112  *
113  * Return:	Success:	The rank (non-negative)
114  *
115  *		Failure:	Negative
116  *
117  * Programmer:	Quincey Koziol
118  *              Friday, January 30, 2004
119  *
120  * Modifications:
121  *
122  *-------------------------------------------------------------------------
123  */
124 int
H5F_mpi_get_rank(const H5F_t * f)125 H5F_mpi_get_rank(const H5F_t *f)
126 {
127     int	ret_value;
128 
129     FUNC_ENTER_NOAPI(FAIL)
130 
131     HDassert(f && f->shared);
132 
133     /* Dispatch to driver */
134     if ((ret_value=H5FD_mpi_get_rank(f->shared->lf)) < 0)
135         HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "driver get_rank request failed")
136 
137 done:
138     FUNC_LEAVE_NOAPI(ret_value)
139 } /* end H5F_mpi_get_rank() */
140 
141 
142 /*-------------------------------------------------------------------------
143  * Function:	H5F_mpi_get_comm
144  *
145  * Purpose:	Retrieves the file's communicator
146  *
147  * Return:	Success:	The communicator (non-negative)
148  *
149  *		Failure:	Negative
150  *
151  * Programmer:	Quincey Koziol
152  *              Friday, January 30, 2004
153  *
154  * Modifications:
155  *
156  *-------------------------------------------------------------------------
157  */
158 MPI_Comm
H5F_mpi_get_comm(const H5F_t * f)159 H5F_mpi_get_comm(const H5F_t *f)
160 {
161     MPI_Comm	ret_value;
162 
163     FUNC_ENTER_NOAPI(MPI_COMM_NULL)
164 
165     HDassert(f && f->shared);
166 
167     /* Dispatch to driver */
168     if ((ret_value=H5FD_mpi_get_comm(f->shared->lf))==MPI_COMM_NULL)
169         HGOTO_ERROR(H5E_VFL, H5E_CANTGET, MPI_COMM_NULL, "driver get_comm request failed")
170 
171 done:
172     FUNC_LEAVE_NOAPI(ret_value)
173 } /* end H5F_mpi_get_comm() */
174 
175 
176 /*-------------------------------------------------------------------------
177  * Function:    H5F_mpi_get_size
178  *
179  * Purpose:     Retrieves the size of an MPI process.
180  *
181  * Return:      Success:        The size (positive)
182  *
183  *              Failure:        Negative
184  *
185  * Programmer:  John Mainzer
186  *              Friday, May 6, 2005
187  *
188  * Modifications:
189  *
190  *-------------------------------------------------------------------------
191  */
192 int
H5F_mpi_get_size(const H5F_t * f)193 H5F_mpi_get_size(const H5F_t *f)
194 {
195     int ret_value;
196 
197     FUNC_ENTER_NOAPI(FAIL)
198 
199     HDassert(f && f->shared);
200 
201     /* Dispatch to driver */
202     if ((ret_value=H5FD_mpi_get_size(f->shared->lf)) < 0)
203         HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "driver get_size request failed")
204 
205 done:
206     FUNC_LEAVE_NOAPI(ret_value)
207 } /* end H5F_mpi_get_size() */
208 
209 
210 /*-------------------------------------------------------------------------
211  * Function:	H5Fset_mpi_atomicity
212  *
213  * Purpose:	Sets the atomicity mode
214  *
215  * Return:	Success:	Non-negative
216  *
217  * 		Failure:	Negative
218  *
219  * Programmer:	Mohamad Chaarawi
220  *		Feb 14, 2012
221  *
222  *-------------------------------------------------------------------------
223  */
224 herr_t
H5Fset_mpi_atomicity(hid_t file_id,hbool_t flag)225 H5Fset_mpi_atomicity(hid_t file_id, hbool_t flag)
226 {
227     H5F_t       *file;
228     herr_t       ret_value = SUCCEED;
229 
230     FUNC_ENTER_API(FAIL)
231     H5TRACE2("e", "ib", file_id, flag);
232 
233     /* Check args */
234     if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE)))
235         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID")
236 
237     /* Check VFD */
238     if(!H5F_HAS_FEATURE(file, H5FD_FEAT_HAS_MPI))
239         HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "incorrect VFL driver, does not support MPI atomicity mode")
240 
241     /* set atomicity value */
242     if (H5FD_set_mpio_atomicity (file->shared->lf, flag) < 0)
243         HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set atomicity flag")
244 
245 done:
246     FUNC_LEAVE_API(ret_value)
247 }
248 
249 
250 /*-------------------------------------------------------------------------
251  * Function:	H5Fget_mpi_atomicity
252  *
253  * Purpose:	Returns the atomicity mode
254  *
255  * Return:	Success:	Non-negative
256  *
257  * 		Failure:	Negative
258  *
259  * Programmer:	Mohamad Chaarawi
260  *		Feb 14, 2012
261  *
262  *-------------------------------------------------------------------------
263  */
264 herr_t
H5Fget_mpi_atomicity(hid_t file_id,hbool_t * flag)265 H5Fget_mpi_atomicity(hid_t file_id, hbool_t *flag)
266 {
267     H5F_t      *file;
268     herr_t     ret_value = SUCCEED;
269 
270     FUNC_ENTER_API(FAIL)
271     H5TRACE2("e", "i*b", file_id, flag);
272 
273     /* Check args */
274     if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE)))
275         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID")
276 
277     /* Check VFD */
278     if(!H5F_HAS_FEATURE(file, H5FD_FEAT_HAS_MPI))
279         HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "incorrect VFL driver, does not support MPI atomicity mode")
280 
281     /* get atomicity value */
282     if (H5FD_get_mpio_atomicity (file->shared->lf, flag) < 0)
283         HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get atomicity flag")
284 
285 done:
286     FUNC_LEAVE_API(ret_value)
287 }
288 
289 
290 /*-------------------------------------------------------------------------
291  * Function:	H5F_mpi_retrieve_comm
292  *
293  * Purpose:	Retrieves an MPI communicator from the file the location ID
294  *              is in. If the loc_id is invalid, the fapl_id is used to
295  *              retrieve the communicator.
296  *
297  * Return:	Success:	Non-negative
298  *
299  * 		Failure:	Negative
300  *
301  * Programmer:	Mohamad Chaarawi
302  *		Feb 14, 2012
303  *
304  *-------------------------------------------------------------------------
305  */
306 herr_t
H5F_mpi_retrieve_comm(hid_t loc_id,hid_t acspl_id,MPI_Comm * mpi_comm)307 H5F_mpi_retrieve_comm(hid_t loc_id, hid_t acspl_id, MPI_Comm *mpi_comm)
308 {
309     herr_t    ret_value = SUCCEED;
310 
311     FUNC_ENTER_NOAPI(FAIL)
312 
313     /* Sanity check */
314     HDassert(mpi_comm);
315 
316     /* Set value to return to invalid MPI comm */
317     *mpi_comm = MPI_COMM_NULL;
318 
319     /* if the loc_id is valid, then get the comm from the file
320        attached to the loc_id */
321     if(H5I_INVALID_HID != loc_id) {
322         H5G_loc_t loc;
323         H5F_t *f;
324 
325         /* Retrieve the file structure */
326         if(H5G_loc(loc_id, &loc) < 0)
327             HGOTO_ERROR(H5E_FILE, H5E_BADTYPE, FAIL, "not a location")
328         f = loc.oloc->file;
329         HDassert(f);
330 
331         /* Check if MPIO driver is used */
332         if(H5F_HAS_FEATURE(f, H5FD_FEAT_HAS_MPI)) {
333             /* retrieve the file communicator */
334             if(MPI_COMM_NULL == (*mpi_comm = H5F_mpi_get_comm(f)))
335                 HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get MPI communicator")
336         } /* end if */
337     } /* end if */
338     /* otherwise, this is from H5Fopen or H5Fcreate and has to be collective */
339     else {
340         H5P_genplist_t *plist;      /* Property list pointer */
341 
342         if(NULL == (plist = H5P_object_verify(acspl_id, H5P_FILE_ACCESS)))
343             HGOTO_ERROR(H5E_FILE, H5E_BADTYPE, FAIL, "not a file access list")
344 
345         if(H5FD_MPIO == H5P_peek_driver(plist)) {
346             const H5FD_mpio_fapl_t *fa; /* MPIO fapl info */
347 
348             if(NULL == (fa = (const H5FD_mpio_fapl_t *)H5P_peek_driver_info(plist)))
349                 HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "bad VFL driver info")
350 
351             *mpi_comm = fa->comm;
352         } /* end if */
353     } /* end else */
354 
355 done:
356     FUNC_LEAVE_NOAPI(ret_value)
357 } /* end H5F_mpi_retrieve_comm */
358 
359 
360 /*-------------------------------------------------------------------------
361  * Function:    H5F_get_mpi_info
362  *
363  * Purpose:     Retrieves MPI File info.
364  *
365  * Return:      Success:        The size (positive)
366  *              Failure:        Negative
367  *
368  *-------------------------------------------------------------------------
369  */
370 herr_t
H5F_get_mpi_info(const H5F_t * f,MPI_Info ** f_info)371 H5F_get_mpi_info(const H5F_t *f, MPI_Info **f_info)
372 {
373     herr_t ret_value = SUCCEED;
374 
375     FUNC_ENTER_NOAPI(FAIL)
376 
377     HDassert(f && f->shared);
378 
379     /* Dispatch to driver */
380     if ((ret_value = H5FD_get_mpi_info(f->shared->lf, (void **)f_info)) < 0)
381         HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get mpi file info")
382 
383 done:
384     FUNC_LEAVE_NOAPI(ret_value)
385 } /* end H5F_get_mpi_info() */
386 #endif /* H5_HAVE_PARALLEL */
387 
388