int ompi_mtl_portals_iprobe(struct mca_mtl_base_module_t* mtl, struct ompi_communicator_t *comm, int src, int tag, int *flag, struct ompi_status_public_t *status) { ptl_match_bits_t match_bits; ptl_match_bits_t ignore_bits; ompi_mtl_portals_event_t *recv_event = NULL; PTL_SET_RECV_BITS(match_bits, ignore_bits, comm->c_contextid, src, tag); /* first, check the queue of processed unexpected messages */ recv_event = ompi_mtl_portals_search_unex_q(match_bits, ignore_bits, true); if (NULL == recv_event) { /* check for new events */ recv_event = ompi_mtl_portals_search_unex_events(match_bits, ignore_bits, true); } if ( NULL != recv_event ) { /* found it */ *flag = 1; status->MPI_SOURCE = PTL_GET_SOURCE(recv_event->ev.match_bits); status->MPI_TAG = PTL_GET_TAG(recv_event->ev.match_bits); status->_count = recv_event->ev.rlength; status->MPI_ERROR = OMPI_SUCCESS; } else { *flag = 0; } return OMPI_SUCCESS; }
/* called when a receive should be progressed */ static int ompi_mtl_portals_recv_progress(ptl_event_t *ev, struct ompi_mtl_portals_request_t* ptl_request) { int ret; switch (ev->type) { case PTL_EVENT_PUT_END: /* make sure the data is in the right place */ ompi_mtl_datatype_unpack(ptl_request->convertor, ev->md.start, ev->mlength); /* set the status */ ptl_request->super.ompi_req->req_status.MPI_SOURCE = PTL_GET_SOURCE(ev->match_bits); ptl_request->super.ompi_req->req_status.MPI_TAG = PTL_GET_TAG(ev->match_bits); ptl_request->super.ompi_req->req_status.MPI_ERROR = (ev->rlength > ev->mlength) ? MPI_ERR_TRUNCATE : MPI_SUCCESS; ptl_request->super.ompi_req->req_status._count = ev->mlength; OPAL_OUTPUT_VERBOSE((50, ompi_mtl_base_output, "recv complete: 0x%016llx\n", ev->match_bits)); ptl_request->super.completion_callback(&ptl_request->super); break; case PTL_EVENT_REPLY_END: /* make sure the data is in the right place */ ompi_mtl_datatype_unpack(ptl_request->convertor, ev->md.start, ev->mlength); ret=PtlMDUnlink(ev->md_handle); if( ret !=PTL_OK) { return ompi_common_portals_error_ptl_to_ompi(ret); } /* set the status - most of this filled in right after issuing the PtlGet*/ ptl_request->super.ompi_req->req_status._count = ev->mlength; OPAL_OUTPUT_VERBOSE((50, ompi_mtl_base_output, "recv complete: 0x%016llx\n", ev->match_bits)); ptl_request->super.completion_callback(&ptl_request->super); break; default: break; } return OMPI_SUCCESS; }
static int ompi_mtl_portals_get_data(ompi_mtl_portals_event_t *recv_event, struct ompi_convertor_t *convertor, ompi_mtl_portals_request_t *ptl_request) { int ret; ptl_md_t md; ptl_handle_md_t md_h; size_t buflen; if (PTL_IS_SHORT_MSG(recv_event->ev.match_bits)) { /* the buffer is sitting in the short message queue */ struct iovec iov; uint32_t iov_count = 1; size_t max_data; ompi_mtl_portals_recv_short_block_t *block = recv_event->ev.md.user_ptr; iov.iov_base = (((char*) recv_event->ev.md.start) + recv_event->ev.offset); iov.iov_len = recv_event->ev.mlength; max_data = iov.iov_len; /* see if this message filled the receive block */ if (recv_event->ev.md.length - (recv_event->ev.offset + recv_event->ev.mlength) < recv_event->ev.md.max_size) { block->full = true; } /* pull out the data */ if (iov.iov_len > 0) { ompi_convertor_unpack(convertor, &iov, &iov_count, &max_data ); } /* if synchronous, return an ack */ if (PTL_IS_SYNC_MSG(recv_event->ev)) { md.length = 0; md.start = (((char*) recv_event->ev.md.start) + recv_event->ev.offset); md.threshold = 1; /* send */ md.options = PTL_MD_EVENT_START_DISABLE; md.user_ptr = NULL; md.eq_handle = ompi_mtl_portals.ptl_eq_h; ret = PtlMDBind(ompi_mtl_portals.ptl_ni_h, md, PTL_UNLINK, &md_h); if (PTL_OK != ret) { opal_output(fileno(stderr)," Error returned from PtlMDBind. Error code - %d \n",ret); abort(); } OPAL_OUTPUT_VERBOSE((50, ompi_mtl_base_output, "acking recv: 0x%016llx\n", recv_event->ev.match_bits)); ret = PtlPut(md_h, PTL_NO_ACK_REQ, recv_event->ev.initiator, OMPI_MTL_PORTALS_ACK_TABLE_ID, 0, recv_event->ev.hdr_data, 0, 0); if (PTL_OK != ret) { opal_output(fileno(stderr)," Error returned from PtlPut. Error code - %d \n",ret); abort(); } } /* finished with our buffer space */ ompi_mtl_portals_return_block_part(&ompi_mtl_portals, block); ompi_convertor_get_packed_size(convertor, &buflen); ptl_request->super.ompi_req->req_status.MPI_SOURCE = PTL_GET_SOURCE(recv_event->ev.match_bits); ptl_request->super.ompi_req->req_status.MPI_TAG = PTL_GET_TAG(recv_event->ev.match_bits); ptl_request->super.ompi_req->req_status.MPI_ERROR = (recv_event->ev.rlength > buflen) ? MPI_ERR_TRUNCATE : MPI_SUCCESS; ptl_request->super.ompi_req->req_status._count = recv_event->ev.mlength; OPAL_OUTPUT_VERBOSE((50, ompi_mtl_base_output, "recv complete: 0x%016llx\n", recv_event->ev.match_bits)); ptl_request->super.completion_callback(&ptl_request->super); } else { ret = ompi_mtl_datatype_recv_buf(convertor, &md.start, &buflen, &ptl_request->free_after); if (OMPI_SUCCESS != ret) { opal_output(fileno(stderr)," Error returned from ompi_mtl_datatype_recv_buf. Error code - %d \n",ret); abort(); } md.length = (recv_event->ev.rlength > buflen) ? buflen : recv_event->ev.rlength; md.threshold = 2; /* send and get */ md.options = PTL_MD_EVENT_START_DISABLE; md.user_ptr = ptl_request; md.eq_handle = ompi_mtl_portals.ptl_eq_h; /* retain because it's unclear how many events we'll get here. Some implementations give just the REPLY, others give SEND and REPLY */ ret = PtlMDBind(ompi_mtl_portals.ptl_ni_h, md, PTL_RETAIN, &md_h); if (PTL_OK != ret) { opal_output(fileno(stderr)," Error returned from ompi_mtl_datatype_recv_buf. Error code - %d \n",ret); abort(); } ptl_request->event_callback = ompi_mtl_portals_recv_progress; ret = PtlGet(md_h, recv_event->ev.initiator, OMPI_MTL_PORTALS_READ_TABLE_ID, 0, recv_event->ev.hdr_data, 0); if (PTL_OK != ret) { opal_output(fileno(stderr)," Error returned from PtlGet. Error code - %d \n",ret); abort(); } ptl_request->super.ompi_req->req_status.MPI_SOURCE = PTL_GET_SOURCE(recv_event->ev.match_bits); ptl_request->super.ompi_req->req_status.MPI_TAG = PTL_GET_TAG(recv_event->ev.match_bits); ptl_request->super.ompi_req->req_status.MPI_ERROR = (recv_event->ev.rlength > buflen) ? MPI_ERR_TRUNCATE : MPI_SUCCESS; } return OMPI_SUCCESS; }