summaryrefslogtreecommitdiffstats
path: root/src/H5FP.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5FP.c')
-rw-r--r--src/H5FP.c284
1 files changed, 284 insertions, 0 deletions
diff --git a/src/H5FP.c b/src/H5FP.c
new file mode 100644
index 0000000..5144119
--- /dev/null
+++ b/src/H5FP.c
@@ -0,0 +1,284 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error Handling */
+#include "H5FPprivate.h" /* Flexible Parallel Functions */
+#include "H5Oprivate.h" /* Object Headers */
+#include "H5TBprivate.h" /* Threaded, Balanced, Binary Trees */
+
+#ifdef H5_HAVE_FPHDF5
+
+#include "mpi.h"
+
+/* Interface initialization */
+#define PABLO_MASK H5FP_mask
+#define INTERFACE_INIT NULL
+
+static int interface_initialize_g = 0;
+
+MPI_Datatype SAP_request_t; /* MPI datatype for the SAP_request obj */
+MPI_Datatype SAP_reply_t; /* MPI datatype for the SAP_reply obj */
+MPI_Datatype SAP_sync_t; /* MPI datatype for the SAP_sync obj */
+
+/* SAP specific variables */
+MPI_Comm H5FP_SAP_COMM; /* Comm we use: Supplied by user */
+MPI_Comm H5FP_SAP_BARRIER_COMM; /* Comm if you want to do a barrier */
+
+unsigned H5FP_sap_rank; /* The rank of the SAP: Supplied by user*/
+unsigned H5FP_capt_rank; /* The rank which tells SAP of opens */
+unsigned H5FP_my_rank; /* Rank of this process in the COMM */
+int H5FP_comm_size; /* Size of the COMM */
+
+/* local functions */
+static herr_t H5FP_commit_sap_datatypes(void);
+static herr_t H5FP_request_sap_stop(void);
+
+/** API Functions **/
+
+/*
+ * Function: H5FPinit
+ * Purpose: Initialize the SAP environment: duplicate the COMM the user
+ * supplies to us, set aside the SAP_RANK as the SAP.
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ * Programmer: Bill Wendling, 26. July, 2002
+ * Modifications:
+ */
+herr_t
+H5FPinit(MPI_Comm comm, int sap_rank)
+{
+ MPI_Group sap_group = MPI_GROUP_NULL, sap_barrier_group = MPI_GROUP_NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_API(H5FPinit, FAIL);
+ H5TRACE2("e","McIs",comm,sap_rank);
+ H5FP_sap_rank = sap_rank;
+
+ if (MPI_Comm_dup(comm, &H5FP_SAP_COMM) != MPI_SUCCESS)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_MPI, FAIL, "MPI_Comm_dup failed");
+
+ if (MPI_Comm_group(H5FP_SAP_COMM, &sap_group) != MPI_SUCCESS)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_MPI, FAIL, "MPI_Comm_group failed");
+
+ if (MPI_Group_excl(sap_group, 1, (int *)&H5FP_sap_rank, &sap_barrier_group)
+ != MPI_SUCCESS)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_MPI, FAIL, "MPI_Comm_group failed");
+
+ if (MPI_Comm_create(H5FP_SAP_COMM, sap_barrier_group, &H5FP_SAP_BARRIER_COMM)
+ != MPI_SUCCESS)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_MPI, FAIL, "MPI_Comm_create failed");
+
+ if (MPI_Comm_size(H5FP_SAP_COMM, &H5FP_comm_size) != MPI_SUCCESS)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_MPI, FAIL, "MPI_Comm_size failed");
+
+ /* we assign the process right after the sap_rank as the one which
+ * will tell the SAP that files have been opened or closed.
+ * we mod it so that we don't go over the size of the communicator. */
+ H5FP_capt_rank = (H5FP_sap_rank + 1) % H5FP_comm_size;
+
+ if (MPI_Comm_rank(H5FP_SAP_COMM, (int *)&H5FP_my_rank) != MPI_SUCCESS)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_MPI, FAIL, "MPI_Comm_rank failed");
+
+ if (H5FP_commit_sap_datatypes() != MPI_SUCCESS)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_MPI, FAIL, "H5FP_commit_sap_datatypes failed");
+
+ if (H5FP_my_rank == H5FP_sap_rank)
+ H5FP_sap_receive_loop();
+
+done:
+ if (sap_group != MPI_GROUP_NULL)
+ MPI_Group_free(&sap_group);
+
+ if (sap_barrier_group != MPI_GROUP_NULL)
+ MPI_Group_free(&sap_barrier_group);
+
+ FUNC_LEAVE(ret_value);
+}
+
+/*
+ * Function: H5FPfinalize
+ * Purpose: Get rid of the initilized environment we setup with H5FPinit.
+ * Mostly just freeing the duplicated COMM object and committed
+ * datatypes.
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ * Programmer: Bill Wendling, 26. July, 2002
+ * Modifications:
+ */
+herr_t
+H5FPfinalize(void)
+{
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_API(H5FPfinalize, FAIL);
+ H5TRACE0("e","");
+
+ if (H5FP_my_rank != H5FP_sap_rank)
+ if (H5FP_request_sap_stop() < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_MPI, FAIL, "Error stopping the SAP");
+
+ if (MPI_Type_free(&SAP_request_t) != MPI_SUCCESS)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_MPI, FAIL, "MPI_Type_free failed");
+
+ if (MPI_Type_free(&SAP_reply_t) != MPI_SUCCESS)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_MPI, FAIL, "MPI_Type_free failed");
+
+ if (MPI_Type_free(&SAP_sync_t) != MPI_SUCCESS)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_MPI, FAIL, "MPI_Type_free failed");
+
+ if (H5FP_SAP_BARRIER_COMM != MPI_COMM_NULL)
+ /* this comm will be NULL for the SAP */
+ if (MPI_Comm_free(&H5FP_SAP_BARRIER_COMM) != MPI_SUCCESS)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_MPI, FAIL, "MPI_Comm_free failed");
+
+ if (MPI_Comm_free(&H5FP_SAP_COMM) != MPI_SUCCESS)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_MPI, FAIL, "MPI_Comm_free failed");
+
+done:
+ FUNC_LEAVE(ret_value);
+}
+
+/** Public Libarary (non-API) Functions **/
+
+/*
+ * Function: H5FP_send_metadata
+ * Purpose: Send a string of metadata to a process.
+ *
+ * NOTE: You should never call this function directly!!
+ * There's special setup for sending a string to a processor
+ * which needs to occur first. The H5FP_request_* and
+ * H5FP_reply_* functions take care of this for you.
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ * Programmer: Bill Wendling, 30. July, 2002
+ * Modifications:
+ */
+herr_t
+H5FP_send_metadata(const char *mdata, int len, int rank)
+{
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(H5FP_send_metadata, FAIL);
+ assert(mdata);
+ assert(len);
+
+ /* casts the CONST away: Okay */
+ if (MPI_Send((void *)mdata, len, MPI_BYTE, rank, H5FP_TAG_METADATA, H5FP_SAP_COMM)
+ != MPI_SUCCESS)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_MPI, FAIL, "MPI_Send failed");
+
+done:
+ FUNC_LEAVE(ret_value);
+}
+
+/** Private Functions **/
+
+/*
+ * Function: H5FP_commit_sap_datatypes
+ * Purpose: Commit the SAP_request_t, SAP_reply_t, and SAP_sync_t
+ * structure datatypes to MPI.
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ * Programmer: Bill Wendling, 26. July, 2002
+ * Modifications:
+ */
+static herr_t
+H5FP_commit_sap_datatypes(void)
+{
+ int block_length[2];
+ MPI_Aint displs[2];
+ MPI_Datatype old_types[2];
+ struct SAP_request req;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(H5FP_commit_sap_datatypes, FAIL);
+
+ /* Commit the SAP_request_t datatype */
+ block_length[0] = 8;
+ block_length[1] = sizeof(req.oid);
+ MPI_Address(&req.req_type, &displs[0]);
+ MPI_Address(&req.oid, &displs[1]);
+ displs[1] -= displs[0];
+ displs[0] -= displs[0];
+ old_types[0] = MPI_INT;
+ old_types[1] = MPI_UNSIGNED_CHAR;
+
+ if (MPI_Type_struct(2, block_length, displs, old_types, &SAP_request_t) != MPI_SUCCESS)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_MPI, FAIL, "MPI_Type_struct failed");
+
+ if (MPI_Type_commit(&SAP_request_t) != MPI_SUCCESS)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_MPI, FAIL, "MPI_Type_commit failed");
+
+ /* Commit the SAP_reply_t datatype */
+ block_length[0] = 3;
+ displs[0] = 0;
+ old_types[0] = MPI_INT;
+
+ if (MPI_Type_struct(1, block_length, displs, old_types, &SAP_reply_t) != MPI_SUCCESS)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_MPI, FAIL, "MPI_Type_struct failed");
+
+ if (MPI_Type_commit(&SAP_reply_t) != MPI_SUCCESS)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_MPI, FAIL, "MPI_Type_commit failed");
+
+ /* Commit the SAP_sync_t datatype */
+ block_length[0] = 8;
+ displs[0] = 0;
+ old_types[0] = MPI_INT;
+
+ if (MPI_Type_struct(1, block_length, displs, old_types, &SAP_sync_t) != MPI_SUCCESS)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_MPI, FAIL, "MPI_Type_struct failed");
+
+ if (MPI_Type_commit(&SAP_sync_t) != MPI_SUCCESS)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_MPI, FAIL, "MPI_Type_commit failed");
+
+done:
+ FUNC_LEAVE(ret_value);
+}
+
+/*
+ * Function: H5FP_request_sap_stop
+ * Purpose: Request that the SAP stop it's loop processing. Each
+ * process should send this to the SAP.
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ * Programmer: Bill Wendling, 02. August, 2002
+ * Modifications:
+ */
+static herr_t
+H5FP_request_sap_stop(void)
+{
+ struct SAP_request req;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(H5FP_request_sap_stop, FAIL);
+
+ HDmemset(&req, 0, sizeof(req));
+ req.req_type = H5FP_REQ_STOP;
+ req.req_id = 0;
+ req.proc_rank = H5FP_my_rank;
+
+ if (MPI_Send(&req, 1, SAP_request_t, (int)H5FP_sap_rank,
+ H5FP_TAG_REQUEST, H5FP_SAP_COMM) != MPI_SUCCESS)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_MPI, FAIL, "MPI_Send failed");
+
+done:
+ FUNC_LEAVE(ret_value);
+}
+
+#endif /* H5_HAVE_FPHDF5 */