static MPIR_Request * create_request(void * hdr, intptr_t hdr_sz, size_t nb) { MPIR_Request * sreq; MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_CREATE_REQUEST); MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_CREATE_REQUEST); sreq = MPIR_Request_create(MPIR_REQUEST_KIND__UNDEFINED); /* --BEGIN ERROR HANDLING-- */ if (sreq == NULL) return NULL; /* --END ERROR HANDLING-- */ MPIR_Object_set_ref(sreq, 2); sreq->kind = MPIR_REQUEST_KIND__SEND; MPIR_Assert(hdr_sz == sizeof(MPIDI_CH3_Pkt_t)); sreq->dev.pending_pkt = *(MPIDI_CH3_Pkt_t *) hdr; sreq->dev.iov[0].MPL_IOV_BUF = (MPL_IOV_BUF_CAST)((char *) &sreq->dev.pending_pkt + nb); sreq->dev.iov[0].MPL_IOV_LEN = hdr_sz - nb; sreq->dev.iov_count = 1; sreq->dev.OnDataAvail = 0; MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_CREATE_REQUEST); return sreq; }
int MPID_Rget_accumulate(const void *origin_addr, int origin_count, MPI_Datatype origin_datatype, void *result_addr, int result_count, MPI_Datatype result_datatype, int target_rank, MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Op op, MPIR_Win * win_ptr, MPIR_Request ** request) { int mpi_errno = MPI_SUCCESS; int dt_contig ATTRIBUTE((unused)); MPIR_Datatype*dtp; MPI_Aint dt_true_lb ATTRIBUTE((unused)); intptr_t data_sz, trg_data_sz; MPIR_Request *ureq; MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_MPID_RGET_ACCUMULATE); MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_MPID_RGET_ACCUMULATE); /* request-based RMA operations are only valid within a passive epoch */ MPIR_ERR_CHKANDJUMP(win_ptr->states.access_state != MPIDI_RMA_PER_TARGET && win_ptr->states.access_state != MPIDI_RMA_LOCK_ALL_CALLED && win_ptr->states.access_state != MPIDI_RMA_LOCK_ALL_ISSUED && win_ptr->states.access_state != MPIDI_RMA_LOCK_ALL_GRANTED, mpi_errno, MPI_ERR_RMA_SYNC, "**rmasync"); /* Create user request, initially cc=1, ref=1 */ ureq = MPIR_Request_create(MPIR_REQUEST_KIND__RMA); MPIR_ERR_CHKANDJUMP(ureq == NULL, mpi_errno, MPI_ERR_OTHER, "**nomemreq"); /* This request is referenced by user and ch3 by default. */ MPIR_Object_set_ref(ureq, 2); /* Note that GACC is only a no-op if no data goes in both directions */ MPIDI_Datatype_get_info(origin_count, origin_datatype, dt_contig, data_sz, dtp, dt_true_lb); MPIDI_Datatype_get_info(origin_count, origin_datatype, dt_contig, trg_data_sz, dtp, dt_true_lb); /* Enqueue or perform the RMA operation */ if (target_rank != MPI_PROC_NULL && (data_sz != 0 || trg_data_sz != 0)) { mpi_errno = MPIDI_CH3I_Get_accumulate(origin_addr, origin_count, origin_datatype, result_addr, result_count, result_datatype, target_rank, target_disp, target_count, target_datatype, op, win_ptr, ureq); if (mpi_errno != MPI_SUCCESS) { MPIR_ERR_POP(mpi_errno); } } else { mpi_errno = MPID_Request_complete(ureq); if (mpi_errno != MPI_SUCCESS) { MPIR_ERR_POP(mpi_errno); } } *request = ureq; fn_exit: MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_MPID_RGET_ACCUMULATE); return mpi_errno; fn_fail: goto fn_exit; }
static MPIR_Request *create_request(MPL_IOV * iov, int iov_count, int iov_offset, size_t nb) { MPIR_Request *sreq; int i; MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_CREATE_REQUEST); MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_CREATE_REQUEST); sreq = MPIR_Request_create(MPIR_REQUEST_KIND__SEND); /* --BEGIN ERROR HANDLING-- */ if (sreq == NULL) return NULL; /* --END ERROR HANDLING-- */ MPIR_Object_set_ref(sreq, 2); for (i = 0; i < iov_count; i++) { sreq->dev.iov[i] = iov[i]; } if (iov_offset == 0) { MPIR_Assert(iov[0].MPL_IOV_LEN == sizeof(MPIDI_CH3_Pkt_t)); sreq->dev.pending_pkt = *(MPIDI_CH3_Pkt_t *) iov[0].MPL_IOV_BUF; sreq->dev.iov[0].MPL_IOV_BUF = (MPL_IOV_BUF_CAST) & sreq->dev.pending_pkt; } sreq->dev.iov[iov_offset].MPL_IOV_BUF = (MPL_IOV_BUF_CAST) ((char *) sreq->dev.iov[iov_offset].MPL_IOV_BUF + nb); sreq->dev.iov[iov_offset].MPL_IOV_LEN -= nb; sreq->dev.iov_count = iov_count; sreq->dev.OnDataAvail = 0; MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_CREATE_REQUEST); return sreq; }
static int MPID_PSP_persistent_init(const void *buf, MPI_Aint count, MPI_Datatype datatype, int rank, int tag, MPIR_Comm *comm, int context_offset, MPIR_Request **request, int (*call)(const void * buf, MPI_Aint count, MPI_Datatype datatype, int rank, int tag, struct MPIR_Comm * comm, int context_offset, MPIR_Request ** request), MPIR_Request_kind_t type) { MPIR_Request *req; struct MPID_DEV_Request_persistent *preq; /* printf("#%d ps--- %s() called\n", MPIDI_Process.my_pg_rank, __func__); printf("#%d buf %p, count %d, datatype 0x%0x, rank %d, tag %d, comm %p, off %d\n", MPIDI_Process.my_pg_rank, buf, count, datatype, rank, tag, comm, context_offset); printf("#%d ctx.id %d ctx.rank %d, ctx.name %s\n", MPIDI_Process.my_pg_rank, comm->context_id, comm->rank, comm->name); */ req = MPIR_Request_create(type); if (unlikely(!req)) goto err_request_recv_create; req->comm = comm; MPIR_Comm_add_ref(comm); req->u.persist.real_request = NULL; MPIDI_PSP_Request_set_completed(req); /* an inactive persistent request is a completed request. */ preq = &req->dev.kind.persistent; preq->buf = (void *)buf; preq->count = count; preq->datatype = datatype; MPID_PSP_Datatype_add_ref(preq->datatype); preq->rank = rank; preq->tag = tag; preq->comm = comm; // MPIR_Comm_add_ref(comm); preq->context_offset = context_offset; preq->call = call; *request = req; return MPI_SUCCESS; /* --- */ err_request_recv_create: return MPI_ERR_NO_MEM; }
int MPII_Genutil_sched_start(MPII_Genutil_sched_t * sched, MPIR_Comm * comm, MPIR_Request ** req) { int mpi_errno = MPI_SUCCESS; int is_complete; int made_progress; MPIR_Request *reqp; MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_MPII_GENUTIL_SCHED_START); MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_MPII_GENUTIL_SCHED_START); /* Create a request */ reqp = MPIR_Request_create(MPIR_REQUEST_KIND__COLL); if (!reqp) MPIR_ERR_SETANDJUMP(mpi_errno, MPI_ERR_OTHER, "**nomem"); *req = reqp; MPIR_Request_add_ref(reqp); /* Make some progress */ mpi_errno = MPII_Genutil_sched_poke(sched, &is_complete, &made_progress); if (is_complete) { MPID_Request_complete(reqp); goto fn_exit; } /* Enqueue schedule and activate progress hook if not already activated */ reqp->u.nbc.coll.sched = (void *) sched; if (coll_queue.head == NULL) MPID_Progress_activate_hook(MPII_Genutil_progress_hook_id); DL_APPEND(coll_queue.head, &(reqp->u.nbc.coll)); MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_MPII_GENUTIL_SCHED_START); fn_exit: return mpi_errno; fn_fail: goto fn_exit; }
int MPID_Put_generic(const void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank, MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPIR_Win *win_ptr, MPIR_Request **request) { int mpi_error = MPI_SUCCESS; MPID_PSP_Datatype_info dt_info; MPID_PSP_packed_msg_t msg; MPID_Win_rank_info *ri = win_ptr->rank_info + target_rank; char *target_buf; #if 0 fprintf(stderr, "int MPID_Put(origin_addr: %p, origin_count: %d, origin_datatype: %08x," " target_rank: %d, target_disp: %d, target_count: %d, target_datatype: %08x," " *win_ptr: %p)\n", origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count, target_datatype, win_ptr); #endif /* Datatype */ MPID_PSP_Datatype_get_info(target_datatype, &dt_info); if(request) { *request = MPIR_Request_create(MPIR_REQUEST_KIND__SEND); (*request)->comm = win_ptr->comm_ptr; MPIR_Comm_add_ref(win_ptr->comm_ptr); } if (unlikely(target_rank == MPI_PROC_NULL)) { goto fn_completed; } /* Request-based RMA operations are only valid within a passive target epoch! */ if(request && win_ptr->epoch_state != MPID_PSP_EPOCH_LOCK && win_ptr->epoch_state != MPID_PSP_EPOCH_LOCK_ALL) { mpi_error = MPI_ERR_RMA_SYNC; goto err_sync_rma; } /* Check that we are within an access/exposure epoch: */ if (win_ptr->epoch_state == MPID_PSP_EPOCH_NONE) { mpi_error = MPI_ERR_RMA_SYNC; goto err_sync_rma; } /* Track access epoch state: */ if (win_ptr->epoch_state == MPID_PSP_EPOCH_FENCE_ISSUED) { win_ptr->epoch_state = MPID_PSP_EPOCH_FENCE; } /* If the put is a local operation, do it here */ if (target_rank == win_ptr->rank || win_ptr->create_flavor == MPI_WIN_FLAVOR_SHARED) { void *base; int disp_unit; if (win_ptr->create_flavor == MPI_WIN_FLAVOR_SHARED) { MPID_PSP_shm_rma_get_base(win_ptr, target_rank, &disp_unit, &base); } else { base = win_ptr->base; disp_unit = win_ptr->disp_unit; } mpi_error = MPIR_Localcopy(origin_addr, origin_count, origin_datatype, (char *) base + disp_unit * target_disp, target_count, target_datatype); if (mpi_error) { goto err_local_copy; } goto fn_completed; } /* Data */ mpi_error = MPID_PSP_packed_msg_prepare(origin_addr, origin_count, origin_datatype, &msg); if (unlikely(mpi_error != MPI_SUCCESS)) goto err_create_packed_msg; MPID_PSP_packed_msg_pack(origin_addr, origin_count, origin_datatype, &msg); target_buf = (char *) ri->base_addr + ri->disp_unit * target_disp; if (0 && MPID_PSP_Datatype_is_contig(&dt_info)) { /* ToDo: reenable pscom buildin rma_write */ /* Contig message. Use pscom buildin rma */ pscom_request_t *req = pscom_request_create(0, 0); req->data_len = msg.msg_sz; req->data = msg.msg; req->connection = ri->con; /* ToDo: need a new io_done. inside io_done, call MPID_PSP_packed_msg_cleanup(msg)!!! */ req->ops.io_done = pscom_request_free; req->xheader.rma_write.dest = target_buf; pscom_post_rma_write(req); /* win_ptr->rma_puts_accs[target_rank]++; / ToDo: Howto receive this? */ } else { unsigned int encode_dt_size = MPID_PSP_Datatype_get_size(&dt_info); unsigned int xheader_len = sizeof(MPID_PSCOM_XHeader_Rma_put_t) + encode_dt_size; pscom_request_t *req = pscom_request_create(xheader_len, sizeof(pscom_request_put_send_t)); MPID_PSCOM_XHeader_Rma_put_t *xheader = &req->xheader.user.put; /* encoded datatype too large for xheader? */ assert(xheader_len < (1<<(8*sizeof(((struct PSCOM_header_net*)0)->xheader_len)))); req->user->type.put_send.msg = msg; req->user->type.put_send.win_ptr = win_ptr; MPID_PSP_Datatype_encode(&dt_info, &xheader->encoded_type); xheader->common.tag = 0; xheader->common.context_id = 0; xheader->common.type = MPID_PSP_MSGTYPE_RMA_PUT; xheader->common._reserved_ = 0; xheader->common.src_rank = win_ptr->rank; /* xheader->target_disp = target_disp; */ xheader->target_count = target_count; xheader->target_buf = target_buf; /* xheader->epoch = ri->epoch_origin; */ xheader->win_ptr = ri->win_ptr; /* remote win_ptr */ req->xheader_len = xheader_len; req->data = msg.msg; req->data_len = msg.msg_sz; req->ops.io_done = rma_put_done; req->user->type.put_send.target_rank = target_rank; req->connection = ri->con; win_ptr->rma_local_pending_cnt++; win_ptr->rma_local_pending_rank[target_rank]++; win_ptr->rma_puts_accs[target_rank]++; if(request) { MPIR_Request *mpid_req = *request; /* TODO: Use a new and 'put_send'-dedicated MPID_DEV_Request_create() */ /* instead of allocating and overloading a common send request. */ pscom_request_free(mpid_req->dev.kind.common.pscom_req); mpid_req->dev.kind.common.pscom_req = req; MPIR_Request_add_ref(mpid_req); req->user->type.put_send.mpid_req = mpid_req; } else { req->user->type.put_send.mpid_req = NULL; } pscom_post_send(req); } fn_exit: return MPI_SUCCESS; fn_completed: if(request) { MPIDI_PSP_Request_set_completed(*request); } return MPI_SUCCESS; /* --- */ err_exit: if(request) { MPIDI_PSP_Request_set_completed(*request); MPIR_Request_free(*request); } return mpi_error; /* --- */ err_create_packed_msg: goto err_exit; err_local_copy: goto err_exit; err_sync_rma: goto err_exit; }
int MPIR_Init_thread(int *argc, char ***argv, int required, int *provided) { int mpi_errno = MPI_SUCCESS; int has_args; int has_env; int thread_provided = 0; int exit_init_cs_on_failure = 0; MPIR_Info *info_ptr; #if defined(MPICH_IS_THREADED) bool cs_initialized = false; #endif /* The threading library must be initialized at the very beginning because * it manages all synchronization objects (e.g., mutexes) that will be * initialized later */ { int thread_err; MPL_thread_init(&thread_err); if (thread_err) goto fn_fail; } #ifdef HAVE_HWLOC MPIR_Process.bindset = hwloc_bitmap_alloc(); hwloc_topology_init(&MPIR_Process.hwloc_topology); MPIR_Process.bindset_is_valid = 0; hwloc_topology_set_io_types_filter(MPIR_Process.hwloc_topology, HWLOC_TYPE_FILTER_KEEP_ALL); if (!hwloc_topology_load(MPIR_Process.hwloc_topology)) { MPIR_Process.bindset_is_valid = !hwloc_get_proc_cpubind(MPIR_Process.hwloc_topology, getpid(), MPIR_Process.bindset, HWLOC_CPUBIND_PROCESS); } #endif #ifdef HAVE_NETLOC MPIR_Process.network_attr.u.tree.node_levels = NULL; MPIR_Process.network_attr.network_endpoint = NULL; MPIR_Process.netloc_topology = NULL; MPIR_Process.network_attr.type = MPIR_NETLOC_NETWORK_TYPE__INVALID; if (strlen(MPIR_CVAR_NETLOC_NODE_FILE)) { mpi_errno = netloc_parse_topology(&MPIR_Process.netloc_topology, MPIR_CVAR_NETLOC_NODE_FILE); if (mpi_errno == NETLOC_SUCCESS) { MPIR_Netloc_parse_topology(MPIR_Process.netloc_topology, &MPIR_Process.network_attr); } } #endif /* For any code in the device that wants to check for runtime * decisions on the value of isThreaded, set a provisional * value here. We could let the MPID_Init routine override this */ #if defined MPICH_IS_THREADED MPIR_ThreadInfo.isThreaded = required == MPI_THREAD_MULTIPLE; #endif /* MPICH_IS_THREADED */ #if defined(MPICH_IS_THREADED) mpi_errno = thread_cs_init(); cs_initialized = true; if (mpi_errno) MPIR_ERR_POP(mpi_errno); #endif /* FIXME: Move to os-dependent interface? */ #ifdef HAVE_WINDOWS_H /* prevent the process from bringing up an error message window if mpich * asserts */ _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR); _CrtSetReportHook2(_CRT_RPTHOOK_INSTALL, assert_hook); #ifdef _WIN64 { /* FIXME: (Windows) This severly degrades performance but fixes alignment * issues with the datatype code. */ /* Prevent misaligned faults on Win64 machines */ UINT mode, old_mode; old_mode = SetErrorMode(SEM_NOALIGNMENTFAULTEXCEPT); mode = old_mode | SEM_NOALIGNMENTFAULTEXCEPT; SetErrorMode(mode); } #endif #endif /* We need this inorder to implement IS_THREAD_MAIN */ #if (MPICH_THREAD_LEVEL >= MPI_THREAD_SERIALIZED) && defined(MPICH_IS_THREADED) { MPID_Thread_self(&MPIR_ThreadInfo.master_thread); } #endif #ifdef HAVE_ERROR_CHECKING /* Because the PARAM system has not been initialized, temporarily * uncondtionally enable error checks. Once the PARAM system is * initialized, this may be reset */ MPIR_Process.do_error_checks = 1; #else MPIR_Process.do_error_checks = 0; #endif /* Initialize necessary subsystems and setup the predefined attribute * values. Subsystems may change these values. */ MPIR_Process.attrs.appnum = -1; MPIR_Process.attrs.host = MPI_PROC_NULL; MPIR_Process.attrs.io = MPI_PROC_NULL; MPIR_Process.attrs.lastusedcode = MPI_ERR_LASTCODE; MPIR_Process.attrs.universe = MPIR_UNIVERSE_SIZE_NOT_SET; MPIR_Process.attrs.wtime_is_global = 0; /* Set the functions used to duplicate attributes. These are * when the first corresponding keyval is created */ MPIR_Process.attr_dup = 0; MPIR_Process.attr_free = 0; #ifdef HAVE_CXX_BINDING /* Set the functions used to call functions in the C++ binding * for reductions and attribute operations. These are null * until a C++ operation is defined. This allows the C code * that implements these operations to not invoke a C++ code * directly, which may force the inclusion of symbols known only * to the C++ compiler (e.g., under more non-GNU compilers, including * Solaris and IRIX). */ MPIR_Process.cxx_call_op_fn = 0; #endif #ifdef HAVE_F08_BINDING MPIR_C_MPI_UNWEIGHTED = MPI_UNWEIGHTED; MPIR_C_MPI_WEIGHTS_EMPTY = MPI_WEIGHTS_EMPTY; #endif /* This allows the device to select an alternative function for * dimsCreate */ MPIR_Process.dimsCreate = 0; /* "Allocate" from the reserved space for builtin communicators and * (partially) initialize predefined communicators. comm_parent is * intially NULL and will be allocated by the device if the process group * was started using one of the MPI_Comm_spawn functions. */ MPIR_Process.comm_world = MPIR_Comm_builtin + 0; MPII_Comm_init(MPIR_Process.comm_world); MPIR_Process.comm_world->handle = MPI_COMM_WORLD; MPIR_Process.comm_world->context_id = 0 << MPIR_CONTEXT_PREFIX_SHIFT; MPIR_Process.comm_world->recvcontext_id = 0 << MPIR_CONTEXT_PREFIX_SHIFT; MPIR_Process.comm_world->comm_kind = MPIR_COMM_KIND__INTRACOMM; /* This initialization of the comm name could be done only when * comm_get_name is called */ MPL_strncpy(MPIR_Process.comm_world->name, "MPI_COMM_WORLD", MPI_MAX_OBJECT_NAME); MPIR_Process.comm_self = MPIR_Comm_builtin + 1; MPII_Comm_init(MPIR_Process.comm_self); MPIR_Process.comm_self->handle = MPI_COMM_SELF; MPIR_Process.comm_self->context_id = 1 << MPIR_CONTEXT_PREFIX_SHIFT; MPIR_Process.comm_self->recvcontext_id = 1 << MPIR_CONTEXT_PREFIX_SHIFT; MPIR_Process.comm_self->comm_kind = MPIR_COMM_KIND__INTRACOMM; MPL_strncpy(MPIR_Process.comm_self->name, "MPI_COMM_SELF", MPI_MAX_OBJECT_NAME); #ifdef MPID_NEEDS_ICOMM_WORLD MPIR_Process.icomm_world = MPIR_Comm_builtin + 2; MPII_Comm_init(MPIR_Process.icomm_world); MPIR_Process.icomm_world->handle = MPIR_ICOMM_WORLD; MPIR_Process.icomm_world->context_id = 2 << MPIR_CONTEXT_PREFIX_SHIFT; MPIR_Process.icomm_world->recvcontext_id = 2 << MPIR_CONTEXT_PREFIX_SHIFT; MPIR_Process.icomm_world->comm_kind = MPIR_COMM_KIND__INTRACOMM; MPL_strncpy(MPIR_Process.icomm_world->name, "MPI_ICOMM_WORLD", MPI_MAX_OBJECT_NAME); /* Note that these communicators are not ready for use - MPID_Init * will setup self and world, and icomm_world if it desires it. */ #endif MPIR_Process.comm_parent = NULL; /* Setup the initial communicator list in case we have * enabled the debugger message-queue interface */ MPII_COMML_REMEMBER(MPIR_Process.comm_world); MPII_COMML_REMEMBER(MPIR_Process.comm_self); /* MPIU_Timer_pre_init(); */ /* Wait for debugger to attach if requested. */ if (MPIR_CVAR_DEBUG_HOLD) { volatile int hold = 1; while (hold) #ifdef HAVE_USLEEP usleep(100); #endif ; } #if defined(HAVE_ERROR_CHECKING) && (HAVE_ERROR_CHECKING == MPID_ERROR_LEVEL_RUNTIME) MPIR_Process.do_error_checks = MPIR_CVAR_ERROR_CHECKING; #endif /* define MPI as initialized so that we can use MPI functions within * MPID_Init if necessary */ OPA_store_int(&MPIR_Process.mpich_state, MPICH_MPI_STATE__IN_INIT); /* We can't acquire any critical sections until this point. Any * earlier the basic data structures haven't been initialized */ MPID_THREAD_CS_ENTER(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX); exit_init_cs_on_failure = 1; /* create MPI_INFO_NULL object */ /* FIXME: Currently this info object is empty, we need to add data to this * as defined by the standard. */ info_ptr = MPIR_Info_builtin + 1; info_ptr->handle = MPI_INFO_ENV; MPIR_Object_set_ref(info_ptr, 1); info_ptr->next = NULL; info_ptr->key = NULL; info_ptr->value = NULL; #ifdef USE_MEMORY_TRACING MPL_trinit(); #endif /* Set the number of tag bits. The device may override this value. */ MPIR_Process.tag_bits = MPIR_TAG_BITS_DEFAULT; /* Create complete request to return in the event of immediately complete * operations. Use a SEND request to cover all possible use-cases. */ MPIR_Process.lw_req = MPIR_Request_create(MPIR_REQUEST_KIND__SEND); MPIR_ERR_CHKANDSTMT(MPIR_Process.lw_req == NULL, mpi_errno, MPIX_ERR_NOREQ, goto fn_fail, "**nomemreq"); MPIR_cc_set(&MPIR_Process.lw_req->cc, 0); mpi_errno = MPID_Init(argc, argv, required, &thread_provided, &has_args, &has_env); if (mpi_errno) MPIR_ERR_POP(mpi_errno); /* Initialize collectives infrastructure */ mpi_errno = MPII_Coll_init(); if (mpi_errno) MPIR_ERR_POP(mpi_errno); /* Set tag_ub as function of tag_bits set by the device */ MPIR_Process.attrs.tag_ub = MPIR_TAG_USABLE_BITS; /* Assert: tag_ub should be a power of 2 minus 1 */ MPIR_Assert(((unsigned) MPIR_Process. attrs.tag_ub & ((unsigned) MPIR_Process.attrs.tag_ub + 1)) == 0); /* Assert: tag_ub is at least the minimum asked for in the MPI spec */ MPIR_Assert(MPIR_Process.attrs.tag_ub >= 32767); /* Capture the level of thread support provided */ MPIR_ThreadInfo.thread_provided = thread_provided; if (provided) *provided = thread_provided; #if defined MPICH_IS_THREADED MPIR_ThreadInfo.isThreaded = (thread_provided == MPI_THREAD_MULTIPLE); #endif /* MPICH_IS_THREADED */ /* FIXME: Define these in the interface. Does Timer init belong here? */ MPII_Timer_init(MPIR_Process.comm_world->rank, MPIR_Process.comm_world->local_size); #ifdef USE_MEMORY_TRACING #ifdef MPICH_IS_THREADED MPL_trconfig(MPIR_Process.comm_world->rank, MPIR_ThreadInfo.isThreaded); #else MPL_trconfig(MPIR_Process.comm_world->rank, 0); #endif /* Indicate that we are near the end of the init step; memory * allocated already will have an id of zero; this helps * separate memory leaks in the initialization code from * leaks in the "active" code */ #endif #ifdef MPL_USE_DBG_LOGGING /* FIXME: This is a hack to handle the common case of two worlds. * If the parent comm is not NULL, we always give the world number * as "1" (false). */ #ifdef MPICH_IS_THREADED MPL_dbg_init(argc, argv, has_args, has_env, MPIR_Process.comm_parent != NULL, MPIR_Process.comm_world->rank, MPIR_ThreadInfo.isThreaded); #else MPL_dbg_init(argc, argv, has_args, has_env, MPIR_Process.comm_parent != NULL, MPIR_Process.comm_world->rank, 0); #endif MPIR_DBG_INIT = MPL_dbg_class_alloc("INIT", "init"); MPIR_DBG_PT2PT = MPL_dbg_class_alloc("PT2PT", "pt2pt"); MPIR_DBG_THREAD = MPL_dbg_class_alloc("THREAD", "thread"); MPIR_DBG_DATATYPE = MPL_dbg_class_alloc("DATATYPE", "datatype"); MPIR_DBG_HANDLE = MPL_dbg_class_alloc("HANDLE", "handle"); MPIR_DBG_COMM = MPL_dbg_class_alloc("COMM", "comm"); MPIR_DBG_BSEND = MPL_dbg_class_alloc("BSEND", "bsend"); MPIR_DBG_ERRHAND = MPL_dbg_class_alloc("ERRHAND", "errhand"); MPIR_DBG_OTHER = MPL_dbg_class_alloc("OTHER", "other"); MPIR_DBG_REQUEST = MPL_dbg_class_alloc("REQUEST", "request"); MPIR_DBG_COLL = MPL_dbg_class_alloc("COLL", "coll"); MPIR_DBG_ASSERT = MPL_dbg_class_alloc("ASSERT", "assert"); MPIR_DBG_STRING = MPL_dbg_class_alloc("STRING", "string"); #endif /* Initialize the C versions of the Fortran link-time constants. * * We now initialize the Fortran symbols from within the Fortran * interface in the routine that first needs the symbols. * This fixes a problem with symbols added by a Fortran compiler that * are not part of the C runtime environment (the Portland group * compilers would do this) */ #if defined(HAVE_FORTRAN_BINDING) && defined(HAVE_MPI_F_INIT_WORKS_WITH_C) mpirinitf_(); #endif /* FIXME: Does this need to come before the call to MPID_InitComplete? * For some debugger support, MPII_Wait_for_debugger may want to use * MPI communication routines to collect information for the debugger */ #ifdef HAVE_DEBUGGER_SUPPORT MPII_Wait_for_debugger(); #endif /* Let the device know that the rest of the init process is completed */ if (mpi_errno == MPI_SUCCESS) mpi_errno = MPID_InitCompleted(); MPID_THREAD_CS_EXIT(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX); /* Make fields of MPIR_Process global visible and set mpich_state * atomically so that MPI_Initialized() etc. are thread safe */ OPA_write_barrier(); OPA_store_int(&MPIR_Process.mpich_state, MPICH_MPI_STATE__POST_INIT); return mpi_errno; fn_fail: /* --BEGIN ERROR HANDLING-- */ /* signal to error handling routines that core services are unavailable */ OPA_store_int(&MPIR_Process.mpich_state, MPICH_MPI_STATE__PRE_INIT); if (exit_init_cs_on_failure) { MPID_THREAD_CS_EXIT(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX); } #if defined(MPICH_IS_THREADED) if (cs_initialized) { MPIR_Thread_CS_Finalize(); } #endif return mpi_errno; /* --END ERROR HANDLING-- */ }
int MPIDI_CH3_iStartMsgv(MPIDI_VC_t * vc, MPL_IOV * iov, int n_iov, MPIR_Request ** sreq_ptr) { MPIR_Request *sreq = NULL; MPIDI_CH3I_VC *vcch = &vc->ch; int mpi_errno = MPI_SUCCESS; MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_MPIDI_CH3_ISTARTMSGV); MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_MPIDI_CH3_ISTARTMSGV); MPIR_Assert(n_iov <= MPL_IOV_LIMIT); /* The SOCK channel uses a fixed length header, the size of which is the * maximum of all possible packet headers */ iov[0].MPL_IOV_LEN = sizeof(MPIDI_CH3_Pkt_t); MPL_DBG_STMT(MPIDI_CH3_DBG_CHANNEL, VERBOSE, MPIDI_DBG_Print_packet((MPIDI_CH3_Pkt_t *) iov[0].MPL_IOV_BUF)); if (vcch->state == MPIDI_CH3I_VC_STATE_CONNECTED) { /* MT */ /* Connection already formed. If send queue is empty attempt to send * data, queuing any unsent data. */ if (MPIDI_CH3I_SendQ_empty(vcch)) { /* MT */ int rc; size_t nb; MPL_DBG_MSG(MPIDI_CH3_DBG_CHANNEL, VERBOSE, "send queue empty, attempting to write"); MPL_DBG_PKT(vcch->conn, (MPIDI_CH3_Pkt_t *) iov[0].MPL_IOV_BUF, "isend"); /* MT - need some signalling to lock down our right to use the * channel, thus insuring that the progress engine does * also try to write */ rc = MPIDI_CH3I_Sock_writev(vcch->sock, iov, n_iov, &nb); if (rc == MPI_SUCCESS) { int offset = 0; MPL_DBG_MSG_D(MPIDI_CH3_DBG_CHANNEL, VERBOSE, "wrote %ld bytes", (unsigned long) nb); while (offset < n_iov) { if (nb >= (int) iov[offset].MPL_IOV_LEN) { nb -= iov[offset].MPL_IOV_LEN; offset++; } else { MPL_DBG_MSG(MPIDI_CH3_DBG_CHANNEL, VERBOSE, "partial write, request enqueued at head"); sreq = create_request(iov, n_iov, offset, nb); if (sreq == NULL) { MPIR_ERR_SETANDJUMP(mpi_errno, MPI_ERR_OTHER, "**nomem"); } MPIDI_CH3I_SendQ_enqueue_head(vcch, sreq); MPL_DBG_MSG_FMT(MPIDI_CH3_DBG_CHANNEL, VERBOSE, (MPL_DBG_FDEST, "posting writev, vc=0x%p, sreq=0x%08x", vc, sreq->handle)); vcch->conn->send_active = sreq; mpi_errno = MPIDI_CH3I_Sock_post_writev(vcch->conn->sock, sreq->dev.iov + offset, sreq->dev.iov_count - offset, NULL); /* --BEGIN ERROR HANDLING-- */ if (mpi_errno != MPI_SUCCESS) { mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_FATAL, __func__, __LINE__, MPI_ERR_OTHER, "**ch3|sock|postwrite", "ch3|sock|postwrite %p %p %p", sreq, vcch->conn, vc); } /* --END ERROR HANDLING-- */ break; } } if (offset == n_iov) { MPL_DBG_MSG(MPIDI_CH3_DBG_CHANNEL, VERBOSE, "entire write complete"); } } /* --BEGIN ERROR HANDLING-- */ else { MPL_DBG_MSG_D(MPIDI_CH3_DBG_CHANNEL, TYPICAL, "ERROR - MPIDI_CH3I_Sock_writev failed, rc=%d", rc); sreq = MPIR_Request_create(MPIR_REQUEST_KIND__SEND); if (sreq == NULL) { MPIR_ERR_SETANDJUMP(mpi_errno, MPI_ERR_OTHER, "**nomem"); } MPIR_cc_set(&(sreq->cc), 0); sreq->status.MPI_ERROR = MPIR_Err_create_code(rc, MPIR_ERR_RECOVERABLE, __func__, __LINE__, MPI_ERR_INTERN, "**ch3|sock|writefailed", "**ch3|sock|writefailed %d", rc); /* Make sure that the caller sees this error */ mpi_errno = sreq->status.MPI_ERROR; } /* --END ERROR HANDLING-- */ } else { MPL_DBG_MSG(MPIDI_CH3_DBG_CHANNEL, VERBOSE, "send in progress, request enqueued"); sreq = create_request(iov, n_iov, 0, 0); if (sreq == NULL) { MPIR_ERR_SETANDJUMP(mpi_errno, MPI_ERR_OTHER, "**nomem"); } MPIDI_CH3I_SendQ_enqueue(vcch, sreq); } } else if (vcch->state == MPIDI_CH3I_VC_STATE_CONNECTING) { MPL_DBG_VCUSE(vc, "connecting. enqueuing request"); /* queue the data so it can be sent after the connection is formed */ sreq = create_request(iov, n_iov, 0, 0); if (sreq == NULL) { MPIR_ERR_SETANDJUMP(mpi_errno, MPI_ERR_OTHER, "**nomem"); } MPIDI_CH3I_SendQ_enqueue(vcch, sreq); } else if (vcch->state == MPIDI_CH3I_VC_STATE_UNCONNECTED) { MPL_DBG_VCUSE(vc, "unconnected. posting connect and enqueuing request"); /* queue the data so it can be sent after the connection is formed */ sreq = create_request(iov, n_iov, 0, 0); if (sreq == NULL) { MPIR_ERR_SETANDJUMP(mpi_errno, MPI_ERR_OTHER, "**nomem"); } MPIDI_CH3I_SendQ_enqueue(vcch, sreq); /* Form a new connection */ MPIDI_CH3I_VC_post_connect(vc); } else if (vcch->state != MPIDI_CH3I_VC_STATE_FAILED) { /* Unable to send data at the moment, so queue it for later */ MPL_DBG_VCUSE(vc, "forming connection, request enqueued"); sreq = create_request(iov, n_iov, 0, 0); if (sreq == NULL) { MPIR_ERR_SETANDJUMP(mpi_errno, MPI_ERR_OTHER, "**nomem"); } MPIDI_CH3I_SendQ_enqueue(vcch, sreq); } /* --BEGIN ERROR HANDLING-- */ else { /* Connection failed, so allocate a request and return an error. */ MPL_DBG_VCUSE(vc, "ERROR - connection failed"); sreq = MPIR_Request_create(MPIR_REQUEST_KIND__SEND); if (sreq == NULL) { MPIR_ERR_SETANDJUMP(mpi_errno, MPI_ERR_OTHER, "**nomem"); } MPIR_cc_set(&(sreq->cc), 0); sreq->status.MPI_ERROR = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, __func__, __LINE__, MPI_ERR_INTERN, "**ch3|sock|connectionfailed", 0); /* Make sure that the caller sees this error */ mpi_errno = sreq->status.MPI_ERROR; } /* --END ERROR HANDLING-- */ fn_fail: *sreq_ptr = sreq; MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_MPIDI_CH3_ISTARTMSGV); return mpi_errno; }
int MPIDI_CH3_iStartMsg(MPIDI_VC_t * vc, void * hdr, intptr_t hdr_sz, MPIR_Request ** sreq_ptr) { MPIR_Request * sreq = NULL; MPIDI_CH3I_VC *vcch = &vc->ch; int mpi_errno = MPI_SUCCESS; MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_MPIDI_CH3_ISTARTMSG); MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_MPIDI_CH3_ISTARTMSG); MPIR_Assert( hdr_sz <= sizeof(MPIDI_CH3_Pkt_t)); /* The SOCK channel uses a fixed length header, the size of which is the maximum of all possible packet headers */ hdr_sz = sizeof(MPIDI_CH3_Pkt_t); MPL_DBG_STMT(MPIDI_CH3_DBG_CHANNEL,VERBOSE, MPIDI_DBG_Print_packet((MPIDI_CH3_Pkt_t*)hdr)); if (vcch->state == MPIDI_CH3I_VC_STATE_CONNECTED) /* MT */ { /* Connection already formed. If send queue is empty attempt to send data, queuing any unsent data. */ if (MPIDI_CH3I_SendQ_empty(vcch)) /* MT */ { size_t nb; int rc; MPL_DBG_MSG(MPIDI_CH3_DBG_CHANNEL,VERBOSE, "send queue empty, attempting to write"); MPL_DBG_PKT(vcch->conn,hdr,"istartmsg"); /* MT: need some signalling to lock down our right to use the channel, thus insuring that the progress engine does not also try to write */ rc = MPIDI_CH3I_Sock_write(vcch->sock, hdr, hdr_sz, &nb); if (rc == MPI_SUCCESS) { MPL_DBG_MSG_D(MPIDI_CH3_DBG_CHANNEL,VERBOSE, "wrote %ld bytes", (unsigned long) nb); if (nb == hdr_sz) { MPL_DBG_MSG_D(MPIDI_CH3_DBG_CHANNEL,VERBOSE, "entire write complete, %" PRIdPTR " bytes", nb); /* done. get us out of here as quickly as possible. */ } else { MPL_DBG_MSG_D(MPIDI_CH3_DBG_CHANNEL,VERBOSE, "partial write of %" PRIdPTR " bytes, request enqueued at head", nb); sreq = create_request(hdr, hdr_sz, nb); if (!sreq) { MPIR_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**nomem"); } MPIDI_CH3I_SendQ_enqueue_head(vcch, sreq); MPL_DBG_MSG_FMT(MPIDI_CH3_DBG_CHANNEL,VERBOSE, (MPL_DBG_FDEST,"posting write, vc=0x%p, sreq=0x%08x", vc, sreq->handle)); vcch->conn->send_active = sreq; mpi_errno = MPIDI_CH3I_Sock_post_write(vcch->conn->sock, sreq->dev.iov[0].MPL_IOV_BUF, sreq->dev.iov[0].MPL_IOV_LEN, sreq->dev.iov[0].MPL_IOV_LEN, NULL); /* --BEGIN ERROR HANDLING-- */ if (mpi_errno != MPI_SUCCESS) { mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_FATAL, FCNAME, __LINE__, MPI_ERR_OTHER, "**ch3|sock|postwrite", "ch3|sock|postwrite %p %p %p", sreq, vcch->conn, vc); goto fn_fail; } /* --END ERROR HANDLING-- */ } } /* --BEGIN ERROR HANDLING-- */ else { MPL_DBG_MSG_D(MPIDI_CH3_DBG_CHANNEL,TYPICAL, "ERROR - MPIDI_CH3I_Sock_write failed, rc=%d", rc); sreq = MPIR_Request_create(MPIR_REQUEST_KIND__UNDEFINED); if (!sreq) { MPIR_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**nomem"); } sreq->kind = MPIR_REQUEST_KIND__SEND; MPIR_cc_set(&(sreq->cc), 0); sreq->status.MPI_ERROR = MPIR_Err_create_code( rc, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_INTERN, "**ch3|sock|writefailed", "**ch3|sock|writefailed %d", rc ); /* Make sure that the caller sees this error */ mpi_errno = sreq->status.MPI_ERROR; } /* --END ERROR HANDLING-- */ } else { MPL_DBG_MSG(MPIDI_CH3_DBG_CHANNEL,VERBOSE, "send in progress, request enqueued"); sreq = create_request(hdr, hdr_sz, 0); if (!sreq) { MPIR_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**nomem"); } MPIDI_CH3I_SendQ_enqueue(vcch, sreq); } } else if (vcch->state == MPIDI_CH3I_VC_STATE_CONNECTING) /* MT */ { MPL_DBG_VCUSE(vc, "connecteding. enqueuing request"); /* queue the data so it can be sent after the connection is formed */ sreq = create_request(hdr, hdr_sz, 0); if (!sreq) { MPIR_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**nomem"); } MPIDI_CH3I_SendQ_enqueue(vcch, sreq); } else if (vcch->state == MPIDI_CH3I_VC_STATE_UNCONNECTED) /* MT */ { MPL_DBG_VCUSE(vc, "unconnected. posting connect and enqueuing request"); /* queue the data so it can be sent after the connection is formed */ sreq = create_request(hdr, hdr_sz, 0); if (!sreq) { MPIR_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**nomem"); } MPIDI_CH3I_SendQ_enqueue(vcch, sreq); /* Form a new connection */ MPIDI_CH3I_VC_post_connect(vc); } else if (vcch->state != MPIDI_CH3I_VC_STATE_FAILED) { /* Unable to send data at the moment, so queue it for later */ MPL_DBG_VCUSE(vc,"forming connection, request enqueued"); sreq = create_request(hdr, hdr_sz, 0); if (!sreq) { MPIR_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**nomem"); } MPIDI_CH3I_SendQ_enqueue(vcch, sreq); } /* --BEGIN ERROR HANDLING-- */ else { /* Connection failed, so allocate a request and return an error. */ MPL_DBG_VCUSE(vc,"ERROR - connection failed"); sreq = MPIR_Request_create(MPIR_REQUEST_KIND__UNDEFINED); if (!sreq) { MPIR_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**nomem"); } sreq->kind = MPIR_REQUEST_KIND__SEND; MPIR_cc_set(&sreq->cc, 0); sreq->status.MPI_ERROR = MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_INTERN, "**ch3|sock|connectionfailed",0 ); /* Make sure that the caller sees this error */ mpi_errno = sreq->status.MPI_ERROR; } /* --END ERROR HANDLING-- */ fn_fail: *sreq_ptr = sreq; MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_MPIDI_CH3_ISTARTMSG); return mpi_errno; }
int MPID_nem_send_iov(MPIDI_VC_t *vc, MPIR_Request **sreq_ptr, MPL_IOV *iov, int n_iov) { int mpi_errno = MPI_SUCCESS; intptr_t data_sz; int i; int iov_data_copied; MPIR_Request *sreq = *sreq_ptr; MPL_IOV *data_iov = &iov[1]; /* iov of just the data, not the header */ int data_n_iov = n_iov - 1; MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_MPID_NEM_SEND_IOV); MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_MPID_NEM_SEND_IOV); if (*sreq_ptr == NULL) { /* create a request */ sreq = MPIR_Request_create(MPIR_REQUEST_KIND__UNDEFINED); MPIR_Assert(sreq != NULL); MPIR_Object_set_ref(sreq, 2); sreq->kind = MPIR_REQUEST_KIND__SEND; sreq->dev.OnDataAvail = 0; } data_sz = 0; for (i = 0; i < data_n_iov; ++i) data_sz += data_iov[i].MPL_IOV_LEN; if (!MPIDI_Request_get_srbuf_flag(sreq)) { MPIDI_CH3U_SRBuf_alloc(sreq, data_sz); /* --BEGIN ERROR HANDLING-- */ if (sreq->dev.tmpbuf_sz == 0) { MPL_DBG_MSG(MPIDI_CH3_DBG_CHANNEL,TYPICAL,"SRBuf allocation failure"); mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_FATAL, FCNAME, __LINE__, MPI_ERR_OTHER, "**nomem", 0); sreq->status.MPI_ERROR = mpi_errno; goto fn_exit; } /* --END ERROR HANDLING-- */ } MPIR_Assert(sreq->dev.tmpbuf_sz >= data_sz); iov_data_copied = 0; for (i = 0; i < data_n_iov; ++i) { MPIR_Memcpy((char*) sreq->dev.tmpbuf + iov_data_copied, data_iov[i].MPL_IOV_BUF, data_iov[i].MPL_IOV_LEN); iov_data_copied += data_iov[i].MPL_IOV_LEN; } mpi_errno = vc->ch.iSendContig(vc, sreq, iov[0].MPL_IOV_BUF, iov[0].MPL_IOV_LEN, sreq->dev.tmpbuf, data_sz); if (mpi_errno) MPIR_ERR_POP(mpi_errno); *sreq_ptr = sreq; fn_exit: MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_MPID_NEM_SEND_IOV); return mpi_errno; fn_fail: goto fn_exit; }
int MPID_nem_ptl_improbe(MPIDI_VC_t *vc, int source, int tag, MPIR_Comm *comm, int context_offset, int *flag, MPIR_Request **message, MPI_Status *status) { int mpi_errno = MPI_SUCCESS; MPID_nem_ptl_vc_area *const vc_ptl = VC_PTL(vc); int ret; ptl_process_t id_any; ptl_me_t me; MPIR_Request *req; MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_MPID_NEM_PTL_IMPROBE); MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_MPID_NEM_PTL_IMPROBE); id_any.phys.nid = PTL_NID_ANY; id_any.phys.pid = PTL_PID_ANY; /* create a request */ req = MPIR_Request_create(MPIR_REQUEST_KIND__MPROBE); MPID_nem_ptl_init_req(req); MPIR_ERR_CHKANDJUMP1(!req, mpi_errno, MPI_ERR_OTHER, "**nomem", "**nomem %s", "MPIR_Request_create"); MPIR_Object_set_ref(req, 2); /* 1 ref for progress engine and 1 ref for us */ REQ_PTL(req)->event_handler = handle_mprobe; /* create a dummy ME to use for searching the list */ me.start = NULL; me.length = 0; me.ct_handle = PTL_CT_NONE; me.uid = PTL_UID_ANY; me.options = ( PTL_ME_OP_PUT | PTL_ME_USE_ONCE ); me.min_free = 0; me.match_bits = NPTL_MATCH(tag, comm->context_id + context_offset, source); if (source == MPI_ANY_SOURCE) me.match_id = id_any; else { if (!vc_ptl->id_initialized) { mpi_errno = MPID_nem_ptl_init_id(vc); if (mpi_errno) MPIR_ERR_POP(mpi_errno); } me.match_id = vc_ptl->id; } if (tag == MPI_ANY_TAG) me.ignore_bits = NPTL_MATCH_IGNORE_ANY_TAG; else me.ignore_bits = NPTL_MATCH_IGNORE; /* submit a search request */ ret = PtlMESearch(MPIDI_nem_ptl_ni, MPIDI_nem_ptl_pt, &me, PTL_SEARCH_DELETE, req); MPIR_ERR_CHKANDJUMP1(ret, mpi_errno, MPI_ERR_OTHER, "**ptlmesearch", "**ptlmesearch %s", MPID_nem_ptl_strerror(ret)); DBG_MSG_MESearch("REG", vc ? vc->pg_rank : 0, me, req); /* wait for search request to complete */ do { mpi_errno = MPID_nem_ptl_poll(FALSE); if (mpi_errno) MPIR_ERR_POP(mpi_errno); } while (!MPIR_Request_is_complete(req)); *flag = REQ_PTL(req)->found; if (*flag) { req->comm = comm; MPIR_Comm_add_ref(comm); MPIR_Request_extract_status(req, status); *message = req; } else { MPIR_Request_free(req); } fn_exit: MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_MPID_NEM_PTL_IMPROBE); return mpi_errno; fn_fail: goto fn_exit; }
{ int ret, mpi_errno = MPI_SUCCESS; MPIDI_nem_ptl_pkt_cancel_send_req_t *req_pkt = (MPIDI_nem_ptl_pkt_cancel_send_req_t *)pkt; MPID_PKT_DECL_CAST(upkt, MPIDI_nem_ptl_pkt_cancel_send_resp_t, resp_pkt); MPIR_Request *search_req, *resp_req; ptl_me_t me; MPID_nem_ptl_vc_area *const vc_ptl = VC_PTL(vc); MPL_DBG_MSG_FMT(MPIDI_CH3_DBG_OTHER,VERBOSE,(MPL_DBG_FDEST, "received cancel send req pkt, sreq=0x%08x, rank=%d, tag=%d, context=%d", req_pkt->sender_req_id, req_pkt->match.parts.rank, req_pkt->match.parts.tag, req_pkt->match.parts.context_id)); /* create a dummy request and search for the message */ /* create a request */ search_req = MPIR_Request_create(MPIR_REQUEST_KIND__MPROBE); MPID_nem_ptl_init_req(search_req); MPIR_ERR_CHKANDJUMP1(!search_req, mpi_errno, MPI_ERR_OTHER, "**nomem", "**nomem %s", "MPIR_Request_create"); MPIR_Object_set_ref(search_req, 2); /* 1 ref for progress engine and 1 ref for us */ /* create a dummy ME to use for searching the list */ me.start = NULL; me.length = 0; me.ct_handle = PTL_CT_NONE; me.uid = PTL_UID_ANY; me.options = ( PTL_ME_OP_PUT | PTL_ME_USE_ONCE ); me.min_free = 0; me.match_bits = NPTL_MATCH(req_pkt->match.parts.tag, req_pkt->match.parts.context_id, req_pkt->match.parts.rank); me.match_id = vc_ptl->id; me.ignore_bits = NPTL_MATCH_IGNORE;