From 133dafd3dcff0882f9443622be809bd48069d75a Mon Sep 17 00:00:00 2001 From: Brian Barrett Date: Tue, 2 Jul 2013 21:42:10 +0000 Subject: [PATCH] First take at Barrier and Ibarrier, both of which seem to work. This commit was SVN r28706. --- ompi/mca/coll/portals4/Makefile.am | 10 +- ompi/mca/coll/portals4/coll_portals4.h | 76 +++- .../mca/coll/portals4/coll_portals4_barrier.c | 338 ++++++++++++++++++ .../coll/portals4/coll_portals4_component.c | 260 ++++++++++++-- .../mca/coll/portals4/coll_portals4_request.c | 55 +++ .../mca/coll/portals4/coll_portals4_request.h | 51 +++ 6 files changed, 760 insertions(+), 30 deletions(-) create mode 100644 ompi/mca/coll/portals4/coll_portals4_barrier.c create mode 100644 ompi/mca/coll/portals4/coll_portals4_request.c create mode 100644 ompi/mca/coll/portals4/coll_portals4_request.h diff --git a/ompi/mca/coll/portals4/Makefile.am b/ompi/mca/coll/portals4/Makefile.am index 85aa68bfd9..8eef95fa15 100644 --- a/ompi/mca/coll/portals4/Makefile.am +++ b/ompi/mca/coll/portals4/Makefile.am @@ -7,9 +7,12 @@ # $HEADER$ # -sources = \ - coll_portals4.h \ - coll_portals4_component.c +local_sources = \ + coll_portals4.h \ + coll_portals4_component.c \ + coll_portals4_barrier.c \ + coll_portals4_request.h \ + coll_portals4_request.c if MCA_BUILD_ompi_coll_portals4_DSO component_noinst = @@ -19,6 +22,7 @@ component_noinst = libmca_coll_portals4.la component_install = endif +AM_CPPFLAGS = $(coll_portals4_CPPFLAGS) mcacomponentdir = $(pkglibdir) mcacomponent_LTLIBRARIES = $(component_install) mca_coll_portals4_la_SOURCES = $(local_sources) diff --git a/ompi/mca/coll/portals4/coll_portals4.h b/ompi/mca/coll/portals4/coll_portals4.h index 2f16c85edc..9f5d621e34 100644 --- a/ompi/mca/coll/portals4/coll_portals4.h +++ b/ompi/mca/coll/portals4/coll_portals4.h @@ -12,22 +12,96 @@ #include "ompi_config.h" +#include + #include "mpi.h" #include "opal/mca/mca.h" #include "ompi/mca/coll/coll.h" #include "ompi/request/request.h" #include "ompi/communicator/communicator.h" +#include "ompi/mca/mtl/portals4/mtl_portals4_endpoint.h" BEGIN_C_DECLS -OMPI_MODULE_DECLSPEC extern const mca_coll_base_component_2_0_0_t mca_coll_portals4_component; + +struct mca_coll_portals4_component_t { + mca_coll_base_component_t super; + + /** Network interface handle for matched interface */ + ptl_handle_ni_t ni_h; + ptl_pt_index_t pt_idx; + ptl_pt_index_t finish_pt_idx; + ptl_handle_eq_t eq_h; + ptl_handle_me_t barrier_unex_me_h; + ptl_handle_md_t md_h; + + ompi_free_list_t requests; /* request free list for the i collectives */ +}; +typedef struct mca_coll_portals4_component_t mca_coll_portals4_component_t; +OMPI_MODULE_DECLSPEC extern mca_coll_portals4_component_t mca_coll_portals4_component; struct mca_coll_portals4_module_t { mca_coll_base_module_t super; + + size_t barrier_count; }; typedef struct mca_coll_portals4_module_t mca_coll_portals4_module_t; OBJ_CLASS_DECLARATION(mca_coll_portals4_module_t); +struct ompi_coll_portals4_request_t; + +/* match/ignore bit manipulation + * + * 01234567 0123 4 567 012 34567 01234567 01234567 01234567 01234567 01234567 + * | | | + * context id |^| type | op count + * ||| | + * +- eager switch +*/ + +#define COLL_PORTALS4_CID_MASK 0xFFF0000000000000ULL +#define COLL_PORTALS4_OP_COUNT_MASK 0x00001FFFFFFFFFFFULL + +#define COLL_PORTALS4_BARRIER 0x01 + +#define MTL_PORTALS4_SET_BITS(match_bits, contextid, eager, type, op_count) \ + { \ + match_bits = contextid; \ + match_bits = (match_bits << 1); \ + match_bits |= (eager & 0x1); \ + match_bits = (match_bits << 6); \ + match_bits |= (type & 0x3F); \ + match_bits = (match_bits << 45); \ + match_bits |= (op_count & 0x1FFFFFFFFFFF); \ + } + +int ompi_coll_portals4_barrier_intra(struct ompi_communicator_t *comm, + mca_coll_base_module_t *module); +int ompi_coll_portals4_ibarrier_intra(struct ompi_communicator_t *comm, + ompi_request_t ** request, + mca_coll_base_module_t *module); +int ompi_coll_portals4_ibarrier_intra_fini(struct ompi_coll_portals4_request_t *request); + + +static inline ptl_process_t +ompi_coll_portals4_get_peer(struct ompi_communicator_t *comm, int rank) +{ + ompi_proc_t *proc = ompi_comm_peer_lookup(comm, rank); + mca_mtl_base_endpoint_t * endpoint = + (mca_mtl_base_endpoint_t*) proc->proc_pml; + return endpoint->ptl_proc; +} + +static inline int +ompi_coll_portals4_get_nchildren(int cube_dim, int hibit, int rank, int size) +{ + int guess = cube_dim - (hibit + 1); + if ((rank | (1 << cube_dim)) >= size) guess--; + if (guess < 0) return 0; + return guess; +} + + END_C_DECLS #endif /* MCA_COLL_PORTALS4_EXPORT_H */ diff --git a/ompi/mca/coll/portals4/coll_portals4_barrier.c b/ompi/mca/coll/portals4/coll_portals4_barrier.c new file mode 100644 index 0000000000..f8eb4e6574 --- /dev/null +++ b/ompi/mca/coll/portals4/coll_portals4_barrier.c @@ -0,0 +1,338 @@ +/* + * Copyright (c) 2013 Sandia National Laboratories. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + + +#include "ompi_config.h" + +#include "coll_portals4.h" +#include "coll_portals4_request.h" + +#include "mpi.h" +#include "ompi/constants.h" +#include "opal/util/bit_ops.h" +#include "ompi/mca/pml/pml.h" +#include "ompi/mca/coll/coll.h" +#include "ompi/mca/coll/base/base.h" + + +int +ompi_coll_portals4_barrier_intra(struct ompi_communicator_t *comm, + mca_coll_base_module_t *module) +{ + mca_coll_portals4_module_t *portals4_module = (mca_coll_portals4_module_t*) module; + int ret, i, dim, hibit, mask, num_msgs; + int size = ompi_comm_size(comm); + int rank = ompi_comm_rank(comm); + ptl_ct_event_t ct; + ptl_handle_ct_t ct_h; + ptl_handle_me_t me_h; + ptl_me_t me; + size_t count; + ptl_match_bits_t match_bits; + + count = opal_atomic_add_size_t(&portals4_module->barrier_count, 1); + + ret = PtlCTAlloc(mca_coll_portals4_component.ni_h, + &ct_h); + if (PTL_OK != ret) { + opal_output_verbose(1, ompi_coll_base_framework.framework_output, + "%s:%d: PtlCTAlloc failed: %d\n", + __FILE__, __LINE__, ret); + return OMPI_ERR_TEMP_OUT_OF_RESOURCE; + } + + MTL_PORTALS4_SET_BITS(match_bits, ompi_comm_get_cid(comm), + 0, COLL_PORTALS4_BARRIER, count); + + /* Build "tree" out of hypercube */ + dim = comm->c_cube_dim; + hibit = opal_hibit(rank, dim); + --dim; + + /* receive space */ + me.start = NULL; + me.length = 0; + me.ct_handle = ct_h; + me.min_free = 0; + me.uid = PTL_UID_ANY; + me.options = PTL_ME_OP_PUT | PTL_ME_EVENT_SUCCESS_DISABLE | + PTL_ME_EVENT_LINK_DISABLE | PTL_ME_EVENT_UNLINK_DISABLE | + PTL_ME_EVENT_CT_COMM | PTL_ME_EVENT_CT_OVERFLOW; + me.match_id.phys.nid = PTL_NID_ANY; + me.match_id.phys.pid = PTL_PID_ANY; + me.match_bits = match_bits; + me.ignore_bits = 0; + ret = PtlMEAppend(mca_coll_portals4_component.ni_h, + mca_coll_portals4_component.pt_idx, + &me, + PTL_PRIORITY_LIST, + NULL, + &me_h); + if (PTL_OK != ret) { + opal_output_verbose(1, ompi_coll_base_framework.framework_output, + "%s:%d: PtlMEAppend failed: %d\n", + __FILE__, __LINE__, ret); + return OMPI_ERROR; + } + + /* calculate number of children to receive from */ + num_msgs = ompi_coll_portals4_get_nchildren(dim + 1, hibit, rank, size); + + /* send to parent when children have sent to us */ + if (rank > 0) { + int parent = rank & ~(1 << hibit); + PtlTriggeredPut(mca_coll_portals4_component.md_h, + 0, + 0, + PTL_NO_ACK_REQ, + ompi_coll_portals4_get_peer(comm, parent), + mca_coll_portals4_component.pt_idx, + match_bits, + 0, + NULL, + 0, + ct_h, + num_msgs); + if (PTL_OK != ret) { + opal_output_verbose(1, ompi_coll_base_framework.framework_output, + "%s:%d: PtlTriggeredPut failed: %d\n", + __FILE__, __LINE__, ret); + return OMPI_ERROR; + } + + /* we'll need to wait for the parent response before the next set of comms */ + num_msgs++; + } + + /* send to children when parent (or all children if root) has sent to us */ + for (i = hibit + 1, mask = 1 << i; i <= dim; ++i, mask <<= 1) { + int peer = rank | mask; + if (peer < size) { + PtlTriggeredPut(mca_coll_portals4_component.md_h, + 0, + 0, + PTL_NO_ACK_REQ, + ompi_coll_portals4_get_peer(comm, peer), + mca_coll_portals4_component.pt_idx, + match_bits, + 0, + NULL, + 0, + ct_h, + num_msgs); + if (PTL_OK != ret) { + opal_output_verbose(1, ompi_coll_base_framework.framework_output, + "%s:%d: PtlTriggeredPut failed: %d\n", + __FILE__, __LINE__, ret); + return OMPI_ERROR; + } + } + } + + /* Wait for all incoming messages */ + ret = PtlCTWait(ct_h, num_msgs, &ct); + if (PTL_OK != ret) { + opal_output_verbose(1, ompi_coll_base_framework.framework_output, + "%s:%d: PtlCTWait failed: %d\n", + __FILE__, __LINE__, ret); + return OMPI_ERROR; + } + + /* cleanup */ + ret = PtlMEUnlink(me_h); + if (PTL_OK != ret) { + opal_output_verbose(1, ompi_coll_base_framework.framework_output, + "%s:%d: PtlMEUnlink failed: %d\n", + __FILE__, __LINE__, ret); + return OMPI_ERROR; + } + ret = PtlCTFree(ct_h); + if (PTL_OK != ret) { + opal_output_verbose(1, ompi_coll_base_framework.framework_output, + "%s:%d: PtlCTFree failed: %d\n", + __FILE__, __LINE__, ret); + return OMPI_ERROR; + } + + return OMPI_SUCCESS; +} + + +int +ompi_coll_portals4_ibarrier_intra(struct ompi_communicator_t *comm, + ompi_request_t **ompi_req, + struct mca_coll_base_module_2_0_0_t *module) +{ + mca_coll_portals4_module_t *portals4_module = (mca_coll_portals4_module_t*) module; + int ret, i, dim, hibit, mask, num_msgs; + int size = ompi_comm_size(comm); + int rank = ompi_comm_rank(comm); + ptl_me_t me; + size_t count; + ptl_match_bits_t match_bits; + ompi_coll_portals4_request_t *request; + + OMPI_COLL_PORTALS4_REQUEST_ALLOC(comm, request); + if (NULL == request) { + opal_output_verbose(1, ompi_coll_base_framework.framework_output, + "%s:%d: request alloc failed\n", + __FILE__, __LINE__); + return OMPI_ERR_TEMP_OUT_OF_RESOURCE; + } + *ompi_req = &request->super; + request->type = OMPI_COLL_PORTALS4_TYPE_BARRIER; + + count = opal_atomic_add_size_t(&portals4_module->barrier_count, 1); + + ret = PtlCTAlloc(mca_coll_portals4_component.ni_h, + &request->ct_h); + if (PTL_OK != ret) { + opal_output_verbose(1, ompi_coll_base_framework.framework_output, + "%s:%d: PtlCTAlloc failed: %d\n", + __FILE__, __LINE__, ret); + return OMPI_ERR_TEMP_OUT_OF_RESOURCE; + } + + MTL_PORTALS4_SET_BITS(match_bits, ompi_comm_get_cid(comm), + 0, COLL_PORTALS4_BARRIER, count); + + /* Build "tree" out of hypercube */ + dim = comm->c_cube_dim; + hibit = opal_hibit(rank, dim); + --dim; + /* calculate number of children to receive from */ + num_msgs = ompi_coll_portals4_get_nchildren(dim + 1, hibit, rank, size); + + /* receive space */ + me.start = NULL; + me.length = 0; + me.ct_handle = request->ct_h; + me.min_free = 0; + me.uid = PTL_UID_ANY; + me.options = PTL_ME_OP_PUT | PTL_ME_EVENT_SUCCESS_DISABLE | + PTL_ME_EVENT_LINK_DISABLE | PTL_ME_EVENT_UNLINK_DISABLE | + PTL_ME_EVENT_CT_COMM | PTL_ME_EVENT_CT_OVERFLOW; + me.match_id.phys.nid = PTL_NID_ANY; + me.match_id.phys.pid = PTL_PID_ANY; + me.match_bits = match_bits; + me.ignore_bits = 0; + ret = PtlMEAppend(mca_coll_portals4_component.ni_h, + mca_coll_portals4_component.pt_idx, + &me, + PTL_PRIORITY_LIST, + NULL, + &request->me_h); + if (PTL_OK != ret) { + opal_output_verbose(1, ompi_coll_base_framework.framework_output, + "%s:%d: PtlMEAppend failed: %d\n", + __FILE__, __LINE__, ret); + return OMPI_ERROR; + } + + /* send to parent when children have sent to us */ + if (rank > 0) { + int parent = rank & ~(1 << hibit); + PtlTriggeredPut(mca_coll_portals4_component.md_h, + 0, + 0, + PTL_NO_ACK_REQ, + ompi_coll_portals4_get_peer(comm, parent), + mca_coll_portals4_component.pt_idx, + match_bits, + 0, + NULL, + 0, + request->ct_h, + num_msgs); + if (PTL_OK != ret) { + opal_output_verbose(1, ompi_coll_base_framework.framework_output, + "%s:%d: PtlTriggeredPut failed: %d\n", + __FILE__, __LINE__, ret); + return OMPI_ERROR; + } + + /* we'll need to wait for the parent response before the next set of comms */ + num_msgs++; + } + + /* send to children when parent (or all children if root) has sent to us */ + for (i = hibit + 1, mask = 1 << i; i <= dim; ++i, mask <<= 1) { + int peer = rank | mask; + if (peer < size) { + PtlTriggeredPut(mca_coll_portals4_component.md_h, + 0, + 0, + PTL_NO_ACK_REQ, + ompi_coll_portals4_get_peer(comm, peer), + mca_coll_portals4_component.pt_idx, + match_bits, + 0, + NULL, + 0, + request->ct_h, + num_msgs); + if (PTL_OK != ret) { + opal_output_verbose(1, ompi_coll_base_framework.framework_output, + "%s:%d: PtlTriggeredPut failed: %d\n", + __FILE__, __LINE__, ret); + return OMPI_ERROR; + } + } + } + + /* Send a put to self when we've received all our messages... */ + PtlPut(mca_coll_portals4_component.md_h, + 0, + 0, + PTL_NO_ACK_REQ, + ompi_coll_portals4_get_peer(comm, rank), + mca_coll_portals4_component.finish_pt_idx, + 0, + 0, + NULL, + (uintptr_t) request); + + if (PTL_OK != ret) { + opal_output_verbose(1, ompi_coll_base_framework.framework_output, + "%s:%d: PtlTriggeredPut failed: %d\n", + __FILE__, __LINE__, ret); + return OMPI_ERROR; + } + + return OMPI_SUCCESS; +} + + +int +ompi_coll_portals4_ibarrier_intra_fini(ompi_coll_portals4_request_t *request) +{ + int ret; + + /* cleanup */ + ret = PtlMEUnlink(request->me_h); + if (PTL_OK != ret) { + opal_output_verbose(1, ompi_coll_base_framework.framework_output, + "%s:%d: PtlMEUnlink failed: %d\n", + __FILE__, __LINE__, ret); + return OMPI_ERROR; + } + ret = PtlCTFree(request->ct_h); + if (PTL_OK != ret) { + opal_output_verbose(1, ompi_coll_base_framework.framework_output, + "%s:%d: PtlCTFree failed: %d\n", + __FILE__, __LINE__, ret); + return OMPI_ERROR; + } + + OPAL_THREAD_LOCK(&ompi_request_lock); + ompi_request_complete(&request->super, true); + OPAL_THREAD_UNLOCK(&ompi_request_lock); + + return OMPI_SUCCESS; +} diff --git a/ompi/mca/coll/portals4/coll_portals4_component.c b/ompi/mca/coll/portals4/coll_portals4_component.c index e69fb4c0f9..d165865d3b 100644 --- a/ompi/mca/coll/portals4/coll_portals4_component.c +++ b/ompi/mca/coll/portals4/coll_portals4_component.c @@ -22,9 +22,11 @@ #include "ompi_config.h" #include "coll_portals4.h" +#include "coll_portals4_request.h" #include "mpi.h" #include "ompi/mca/coll/coll.h" +#include "ompi/mca/coll/base/base.h" const char *mca_coll_portals4_component_version_string = "Open MPI Portals 4 collective MCA component version " OMPI_VERSION; @@ -38,33 +40,38 @@ static mca_coll_base_module_t* portals4_comm_query(struct ompi_communicator_t *c int *priority); static int portals4_module_enable(mca_coll_base_module_t *module, struct ompi_communicator_t *comm); +static int portals4_progress(void); -const mca_coll_base_component_2_0_0_t mca_coll_portals4_component = { - - /* First, the mca_component_t struct containing meta information - * about the component itself */ +mca_coll_portals4_component_t mca_coll_portals4_component = { { - MCA_COLL_BASE_VERSION_2_0_0, + /* First, the mca_component_t struct containing meta information + * about the component itself */ - /* Component name and version */ - "portals4", - OMPI_MAJOR_VERSION, - OMPI_MINOR_VERSION, - OMPI_RELEASE_VERSION, + { + MCA_COLL_BASE_VERSION_2_0_0, - /* Component open and close functions */ - NULL, - NULL, - NULL, - portals4_register - }, - { - }, + /* Component name and version */ + "portals4", + OMPI_MAJOR_VERSION, + OMPI_MINOR_VERSION, + OMPI_RELEASE_VERSION, - /* Initialization / querying functions */ - mca_coll_portals4_init_query, - mca_coll_portals4_comm_query + /* Component open and close functions */ + NULL, + NULL, + NULL, + portals4_register + }, + { + /* The component is not checkpoint ready */ + MCA_BASE_METADATA_PARAM_NONE + }, + + /* Initialization / querying functions */ + portals4_init_query, + portals4_comm_query + } }; @@ -72,7 +79,7 @@ static int portals4_register(void) { mca_coll_portals4_priority = 100; - (void) mca_base_component_var_register(&mca_coll_portals4_component.collm_version, "priority", + (void) mca_base_component_var_register(&mca_coll_portals4_component.super.collm_version, "priority", "Priority of the portals4 coll component", MCA_BASE_VAR_TYPE_INT, NULL, 0, 0, OPAL_INFO_LVL_9, @@ -93,6 +100,154 @@ static int portals4_init_query(bool enable_progress_threads, bool enable_mpi_threads) { + int ret; + ptl_md_t md; + ptl_me_t me; + + /* Initialize Portals and create a physical, matching interface */ + ret = PtlNIInit(PTL_IFACE_DEFAULT, + PTL_NI_PHYSICAL | PTL_NI_MATCHING, + PTL_PID_ANY, + NULL, + NULL, + &mca_coll_portals4_component.ni_h); + if (PTL_OK != ret) { + opal_output_verbose(1, ompi_coll_base_framework.framework_output, + "%s:%d: PtlNIInit failed: %d\n", + __FILE__, __LINE__, ret); + return OMPI_ERROR; + } + + /* FIX ME: Need to make sure our ID matches with the MTL... */ + + ret = PtlEQAlloc(mca_coll_portals4_component.ni_h, + 4096, + &mca_coll_portals4_component.eq_h); + if (PTL_OK != ret) { + opal_output_verbose(1, ompi_coll_base_framework.framework_output, + "%s:%d: PtlEQAlloc failed: %d\n", + __FILE__, __LINE__, ret); + return OMPI_ERROR; + } + + ret = PtlPTAlloc(mca_coll_portals4_component.ni_h, + 0, + mca_coll_portals4_component.eq_h, + 15, + &mca_coll_portals4_component.pt_idx); + if (PTL_OK != ret) { + opal_output_verbose(1, ompi_coll_base_framework.framework_output, + "%s:%d: PtlPTAlloc failed: %d\n", + __FILE__, __LINE__, ret); + return OMPI_ERROR; + } + + ret = PtlPTAlloc(mca_coll_portals4_component.ni_h, + 0, + mca_coll_portals4_component.eq_h, + 16, + &mca_coll_portals4_component.finish_pt_idx); + if (PTL_OK != ret) { + opal_output_verbose(1, ompi_coll_base_framework.framework_output, + "%s:%d: PtlPTAlloc failed: %d\n", + __FILE__, __LINE__, ret); + return OMPI_ERROR; + } + + /* send space... */ + md.start = 0; + md.length = PTL_SIZE_MAX; + md.options = 0; + md.eq_handle = PTL_EQ_NONE; + md.ct_handle = PTL_CT_NONE; + ret = PtlMDBind(mca_coll_portals4_component.ni_h, + &md, + &mca_coll_portals4_component.md_h); + if (PTL_OK != ret) { + opal_output_verbose(1, ompi_coll_base_framework.framework_output, + "%s:%d: PtlMDBind failed: %d\n", + __FILE__, __LINE__, ret); + return OMPI_ERROR; + } + + /* setup finish ack ME */ + me.start = NULL; + me.length = 0; + me.ct_handle = PTL_CT_NONE; + me.min_free = 0; + me.uid = PTL_UID_ANY; + me.options = PTL_ME_OP_PUT | + PTL_ME_EVENT_LINK_DISABLE | PTL_ME_EVENT_UNLINK_DISABLE; + me.match_id.phys.nid = PTL_NID_ANY; + me.match_id.phys.pid = PTL_PID_ANY; + me.match_bits = 0; + me.ignore_bits = 0; + + ret = PtlMEAppend(mca_coll_portals4_component.ni_h, + mca_coll_portals4_component.finish_pt_idx, + &me, + PTL_OVERFLOW_LIST, + NULL, + &mca_coll_portals4_component.barrier_unex_me_h); + if (PTL_OK != ret) { + opal_output_verbose(1, ompi_coll_base_framework.framework_output, + "%s:%d: PtlMEAppend of barrier unexpected failed: %d\n", + __FILE__, __LINE__, ret); + return OMPI_ERROR; + } + + /* Setup Barrier unexpected arena, which is not per-communicator specific. */ + me.start = NULL; + me.length = 0; + me.ct_handle = PTL_CT_NONE; + me.min_free = 0; + me.uid = PTL_UID_ANY; + me.options = PTL_ME_OP_PUT | PTL_ME_EVENT_SUCCESS_DISABLE | + PTL_ME_EVENT_LINK_DISABLE | PTL_ME_EVENT_UNLINK_DISABLE; + me.match_id.phys.nid = PTL_NID_ANY; + me.match_id.phys.pid = PTL_PID_ANY; + MTL_PORTALS4_SET_BITS(me.match_bits, 0, 0, COLL_PORTALS4_BARRIER, 0); + me.ignore_bits = COLL_PORTALS4_CID_MASK | COLL_PORTALS4_OP_COUNT_MASK; + + ret = PtlMEAppend(mca_coll_portals4_component.ni_h, + mca_coll_portals4_component.pt_idx, + &me, + PTL_OVERFLOW_LIST, + NULL, + &mca_coll_portals4_component.barrier_unex_me_h); + if (PTL_OK != ret) { + opal_output_verbose(1, ompi_coll_base_framework.framework_output, + "%s:%d: PtlMEAppend of barrier unexpected failed: %d\n", + __FILE__, __LINE__, ret); + return OMPI_ERROR; + } + + OBJ_CONSTRUCT(&mca_coll_portals4_component.requests, ompi_free_list_t); + ret = ompi_free_list_init(&mca_coll_portals4_component.requests, + sizeof(ompi_coll_portals4_request_t), + OBJ_CLASS(ompi_coll_portals4_request_t), + 8, + 0, + 8, + NULL); + if (OMPI_SUCCESS != ret) { + opal_output_verbose(1, ompi_coll_base_framework.framework_output, + "%s:%d: ompi_free_list_init failed: %d\n", + __FILE__, __LINE__, ret); + return ret; + } + + /* activate progress callback */ + ret = opal_progress_register(portals4_progress); + if (OMPI_SUCCESS != ret) { + opal_output_verbose(1, ompi_coll_base_framework.framework_output, + "%s:%d: opal_progress_register failed: %d\n", + __FILE__, __LINE__, ret); + return OMPI_ERROR; + } + + /* FIX ME: Need to find a way to shutdown when we're all done... */ + return OMPI_SUCCESS; } @@ -106,15 +261,23 @@ mca_coll_base_module_t * portals4_comm_query(struct ompi_communicator_t *comm, int *priority) { - int size; mca_coll_portals4_module_t *portals4_module; + /* For now, we don't support intercommunicators */ + if (OMPI_COMM_IS_INTER(comm)) { + return NULL; + } + portals4_module = OBJ_NEW(mca_coll_portals4_module_t); if (NULL == portals4_module) return NULL; *priority = mca_coll_portals4_priority; - portals4_module->super.coll_module_enable = mca_coll_portals4_module_enable; + portals4_module->super.coll_module_enable = portals4_module_enable; portals4_module->super.ft_event = NULL; + portals4_module->super.coll_barrier = ompi_coll_portals4_barrier_intra; + portals4_module->super.coll_ibarrier = ompi_coll_portals4_ibarrier_intra; + + portals4_module->barrier_count = 0; return &(portals4_module->super); } @@ -123,13 +286,58 @@ portals4_comm_query(struct ompi_communicator_t *comm, /* * Init module on the communicator */ -int +static int portals4_module_enable(mca_coll_base_module_t *module, - struct ompi_communicator_t *comm) + struct ompi_communicator_t *comm) { return OMPI_SUCCESS; } + +static int +portals4_progress(void) +{ + int count = 0, ret; + ptl_event_t ev; + ompi_coll_portals4_request_t *ptl_request; + + while (true) { + ret = PtlEQGet(mca_coll_portals4_component.eq_h, &ev); + if (PTL_OK == ret) { + OPAL_OUTPUT_VERBOSE((60, ompi_coll_base_framework.framework_output, + "Found event of type %d\n", ev.type)); + count++; + if (PTL_OK == ev.ni_fail_type) { + assert(0 != ev.hdr_data); + ptl_request = (ompi_coll_portals4_request_t*) ev.hdr_data; + assert(NULL != ptl_request); + switch (ptl_request->type) { + case OMPI_COLL_PORTALS4_TYPE_BARRIER: + ompi_coll_portals4_ibarrier_intra_fini(ptl_request); + break; + } + } else { + opal_output(ompi_coll_base_framework.framework_output, + "Error reported in event: %d\n", ev.ni_fail_type); + abort(); + } + } else if (PTL_EQ_EMPTY == ret) { + break; + } else if (PTL_EQ_DROPPED == ret) { + opal_output(ompi_coll_base_framework.framework_output, + "Flow control situation without recovery (EQ_DROPPED)\n"); + abort(); + } else { + opal_output(ompi_coll_base_framework.framework_output, + "Error returned from PtlEQGet: %d", ret); + break; + } + } + + return count; +} + + OBJ_CLASS_INSTANCE(mca_coll_portals4_module_t, mca_coll_base_module_t, NULL, NULL); diff --git a/ompi/mca/coll/portals4/coll_portals4_request.c b/ompi/mca/coll/portals4/coll_portals4_request.c new file mode 100644 index 0000000000..4dc74fbabe --- /dev/null +++ b/ompi/mca/coll/portals4/coll_portals4_request.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2013 Sandia National Laboratories. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include "ompi_config.h" + +#include "ompi/request/request.h" + +#include "coll_portals4.h" +#include "coll_portals4_request.h" + +static int +request_cancel(struct ompi_request_t *request, int complete) +{ + return MPI_ERR_REQUEST; +} + +static int +request_free(struct ompi_request_t **ompi_req) +{ + ompi_coll_portals4_request_t *request = + (ompi_coll_portals4_request_t*) *ompi_req; + + if (true != request->super.req_complete) { + return MPI_ERR_REQUEST; + } + + OMPI_COLL_PORTALS4_REQUEST_RETURN(request); + + *ompi_req = MPI_REQUEST_NULL; + + return OMPI_SUCCESS; +} + +static +void +request_construct(ompi_coll_portals4_request_t *request) +{ + request->super.req_type = OMPI_REQUEST_WIN; + request->super.req_status._cancelled = 0; + request->super.req_free = request_free; + request->super.req_cancel = request_cancel; + request->ct_h = PTL_INVALID_HANDLE; + request->me_h = PTL_INVALID_HANDLE; +} + +OBJ_CLASS_INSTANCE(ompi_coll_portals4_request_t, + ompi_request_t, + request_construct, + NULL); diff --git a/ompi/mca/coll/portals4/coll_portals4_request.h b/ompi/mca/coll/portals4/coll_portals4_request.h new file mode 100644 index 0000000000..d59c419642 --- /dev/null +++ b/ompi/mca/coll/portals4/coll_portals4_request.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013 Sandia National Laboratories. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef COLL_PORTALS4_REQUEST_H +#define COLL_PORTALS4_REQUEST_H + +#include "ompi/request/request.h" + +enum ompi_coll_portals4_request_type_t { + OMPI_COLL_PORTALS4_TYPE_BARRIER, +}; +typedef enum ompi_coll_portals4_request_type_t ompi_coll_portals4_request_type_t; + +struct ompi_coll_portals4_request_t { + ompi_request_t super; + ompi_coll_portals4_request_type_t type; + ptl_handle_ct_t ct_h; + ptl_handle_me_t me_h; +}; +typedef struct ompi_coll_portals4_request_t ompi_coll_portals4_request_t; + +OBJ_CLASS_DECLARATION(ompi_coll_portals4_request_t); + +#define OMPI_COLL_PORTALS4_REQUEST_ALLOC(comm, req) \ + do { \ + int rc; \ + ompi_free_list_item_t *item; \ + OMPI_FREE_LIST_WAIT(&mca_coll_portals4_component.requests, \ + item, rc); \ + req = (ompi_coll_portals4_request_t*) item; \ + OMPI_REQUEST_INIT(&req->super, false); \ + req->super.req_mpi_object.comm = comm; \ + req->super.req_complete = false; \ + req->super.req_state = OMPI_REQUEST_ACTIVE; \ + } while (0) + +#define OMPI_COLL_PORTALS4_REQUEST_RETURN(req) \ + do { \ + OMPI_REQUEST_FINI(&request->super); \ + OMPI_FREE_LIST_RETURN(&mca_coll_portals4_component.requests, \ + (ompi_free_list_item_t*) req); \ + } while (0) + + +#endif