Beispiel #1
0
void
MPIDI_Request_uncomplete(MPID_Request *req)
{
  int count;
  MPIU_Object_add_ref(req);
  MPIR_cc_incr(req->cc_ptr, &count);
}
Beispiel #2
0
int MPIDI_VCRT_Add_ref(struct MPIDI_VCRT *vcrt)
{
    MPIDI_STATE_DECL(MPID_STATE_MPIDI_VCRT_ADD_REF);

    MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_VCRT_ADD_REF);
    MPIU_Object_add_ref(vcrt);
    MPIU_DBG_MSG_FMT(REFCOUNT,TYPICAL,(MPIU_DBG_FDEST, "Incr VCRT %p ref count",vcrt));
    MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_VCRT_ADD_REF);
    return MPI_SUCCESS;
}
Beispiel #3
0
int MPIR_Comm_delete_internal(MPID_Comm * comm_ptr)
{
    int in_use;
    int mpi_errno = MPI_SUCCESS;
    MPID_MPI_STATE_DECL(MPID_STATE_COMM_DELETE_INTERNAL);

    MPID_MPI_FUNC_ENTER(MPID_STATE_COMM_DELETE_INTERNAL);

    MPIU_Assert(MPIU_Object_get_ref(comm_ptr) == 0);    /* sanity check */

    /* Remove the attributes, executing the attribute delete routine.
     * Do this only if the attribute functions are defined.
     * This must be done first, because if freeing the attributes
     * returns an error, the communicator is not freed */
    if (MPIR_Process.attr_free && comm_ptr->attributes) {
        /* Temporarily add a reference to this communicator because
         * the attr_free code requires a valid communicator */
        MPIU_Object_add_ref(comm_ptr);
        mpi_errno = MPIR_Process.attr_free(comm_ptr->handle, &comm_ptr->attributes);
        /* Release the temporary reference added before the call to
         * attr_free */
        MPIU_Object_release_ref(comm_ptr, &in_use);
    }

    /* If the attribute delete functions return failure, the
     * communicator must not be freed.  That is the reason for the
     * test on mpi_errno here. */
    if (mpi_errno == MPI_SUCCESS) {
        /* If this communicator is our parent, and we're disconnecting
         * from the parent, mark that fact */
        if (MPIR_Process.comm_parent == comm_ptr)
            MPIR_Process.comm_parent = NULL;

        /* Notify the device that the communicator is about to be
         * destroyed */
        mpi_errno = MPID_Dev_comm_destroy_hook(comm_ptr);
        if (mpi_errno)
            MPIR_ERR_POP(mpi_errno);

        /* Free info hints */
        if (comm_ptr->info != NULL) {
            MPIU_Info_free(comm_ptr->info);
        }

        /* release our reference to the collops structure, comes after the
         * destroy_hook to allow the device to manage these vtables in a custom
         * fashion */
        if (comm_ptr->coll_fns && --comm_ptr->coll_fns->ref_count == 0) {
            MPIU_Free(comm_ptr->coll_fns);
            comm_ptr->coll_fns = NULL;
        }

        if (comm_ptr->comm_kind == MPID_INTERCOMM && comm_ptr->local_comm)
            MPIR_Comm_release(comm_ptr->local_comm);

        /* Free the local and remote groups, if they exist */
        if (comm_ptr->local_group)
            MPIR_Group_release(comm_ptr->local_group);
        if (comm_ptr->remote_group)
            MPIR_Group_release(comm_ptr->remote_group);

        /* free the intra/inter-node communicators, if they exist */
        if (comm_ptr->node_comm)
            MPIR_Comm_release(comm_ptr->node_comm);
        if (comm_ptr->node_roots_comm)
            MPIR_Comm_release(comm_ptr->node_roots_comm);
        if (comm_ptr->intranode_table != NULL)
            MPIU_Free(comm_ptr->intranode_table);
        if (comm_ptr->internode_table != NULL)
            MPIU_Free(comm_ptr->internode_table);

        /* Free the context value.  This should come after freeing the
         * intra/inter-node communicators since those free calls won't
         * release this context ID and releasing this before then could lead
         * to races once we make threading finer grained. */
        /* This must be the recvcontext_id (i.e. not the (send)context_id)
         * because in the case of intercommunicators the send context ID is
         * allocated out of the remote group's bit vector, not ours. */
        MPIR_Free_contextid(comm_ptr->recvcontext_id);

        /* We need to release the error handler */
        if (comm_ptr->errhandler &&
            !(HANDLE_GET_KIND(comm_ptr->errhandler->handle) == HANDLE_KIND_BUILTIN)) {
            int errhInuse;
            MPIR_Errhandler_release_ref(comm_ptr->errhandler, &errhInuse);
            if (!errhInuse) {
                MPIU_Handle_obj_free(&MPID_Errhandler_mem, comm_ptr->errhandler);
            }
        }

        /* Remove from the list of active communicators if
         * we are supporting message-queue debugging.  We make this
         * conditional on having debugger support since the
         * operation is not constant-time */
        MPIR_COMML_FORGET(comm_ptr);

        /* Check for predefined communicators - these should not
         * be freed */
        if (!(HANDLE_GET_KIND(comm_ptr->handle) == HANDLE_KIND_BUILTIN))
            MPIU_Handle_obj_free(&MPID_Comm_mem, comm_ptr);
    }
    else {
        /* If the user attribute free function returns an error,
         * then do not free the communicator */
        MPIR_Comm_add_ref(comm_ptr);
    }

  fn_exit:
    MPID_MPI_FUNC_EXIT(MPID_STATE_COMM_DELETE_INTERNAL);
    return mpi_errno;
  fn_fail:
    goto fn_exit;
}
int MPID_Startall(int count, MPID_Request * requests[])
{
  int rc=MPI_SUCCESS, i;
  for (i = 0; i < count; i++)
    {
      MPID_Request * const preq = requests[i];
      switch(MPID_Request_getType(preq))
        {
        case MPIDI_DCMF_REQUEST_TYPE_RECV:
          {
            rc = MPID_Irecv(preq->dcmf.userbuf,
                            preq->dcmf.userbufcount,
                            preq->dcmf.datatype,
                            MPID_Request_getMatchRank(preq),
                            MPID_Request_getMatchTag(preq),
                            preq->comm,
                            MPID_Request_getMatchCtxt(preq) - preq->comm->recvcontext_id,
                            &preq->partner_request);
            break;
          }
        case MPIDI_DCMF_REQUEST_TYPE_SEND:
          {
            rc = MPID_Isend(preq->dcmf.userbuf,
                            preq->dcmf.userbufcount,
                            preq->dcmf.datatype,
                            MPID_Request_getMatchRank(preq),
                            MPID_Request_getMatchTag(preq),
                            preq->comm,
                            MPID_Request_getMatchCtxt(preq) - preq->comm->context_id,
                            &preq->partner_request);
            break;
          }
        case MPIDI_DCMF_REQUEST_TYPE_RSEND:
          {
            rc = MPID_Irsend(preq->dcmf.userbuf,
                             preq->dcmf.userbufcount,
                             preq->dcmf.datatype,
                             MPID_Request_getMatchRank(preq),
                             MPID_Request_getMatchTag(preq),
                             preq->comm,
                             MPID_Request_getMatchCtxt(preq) - preq->comm->context_id,
                             &preq->partner_request);
            break;
          }
        case MPIDI_DCMF_REQUEST_TYPE_SSEND:
          {
            rc = MPID_Issend(preq->dcmf.userbuf,
                             preq->dcmf.userbufcount,
                             preq->dcmf.datatype,
                             MPID_Request_getMatchRank(preq),
                             MPID_Request_getMatchTag(preq),
                             preq->comm,
                             MPID_Request_getMatchCtxt(preq) - preq->comm->context_id,
                             &preq->partner_request);
            break;
          }
        case MPIDI_DCMF_REQUEST_TYPE_BSEND:
          {
            rc = MPIR_Bsend_isend(preq->dcmf.userbuf,
                                  preq->dcmf.userbufcount,
                                  preq->dcmf.datatype,
                                  MPID_Request_getMatchRank(preq),
                                  MPID_Request_getMatchTag(preq),
                                  preq->comm,
                                  BSEND_INIT,
                                  &preq->partner_request);
            /*
             * MPICH2 maintains an independant reference to the child,
             * but doesn't refcount it.  Since they actually call
             * MPI_Test() on the child request (which will release a
             * ref iff the request is complete), we have to increment
             * the ref_count so that it doesn't get freed from under
             * us.
             */
            if (preq->partner_request != NULL)
              MPIU_Object_add_ref(preq->partner_request);
            break;
          }

        default:
          {
            rc = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_FATAL, "MPID_Startall", __LINE__, MPI_ERR_INTERN,"**ch3|badreqtype","**ch3|badreqtype %d",MPID_Request_getType(preq));
          }

        } /* switch should end here, bug fixed. */

      if (rc == MPI_SUCCESS)
      {
        preq->status.MPI_ERROR = MPI_SUCCESS;
        if (MPID_Request_getType(preq) == MPIDI_DCMF_REQUEST_TYPE_BSEND)
          {
            /*
             * Complete a persistent Bsend immediately.
             *
             * Because the child of a persistent Bsend is just a
             * normal Isend on a temp buffer, we don't need to wait on
             * the child when the user calls MPI_Wait on the parent.
             * Therefore, disconnect the cc_ptr link to the child and
             * mark the parent complete.
             */
            preq->cc = 0;
            preq->cc_ptr = &preq->cc;
          }
        else
          preq->cc_ptr = &preq->partner_request->cc;
      }
      else
      {
        /* If a failure occurs attempting to start the request,
          then we assume that partner request was not created,
          and stuff the error code in the persistent request.
          The wait and test routines will look at the error code
          in the persistent request if a partner request is not present. */
        preq->partner_request = NULL;
        preq->status.MPI_ERROR = rc;
        preq->cc_ptr = &preq->cc;
        preq->cc = 0;
      }
  } /* for */
  return rc;
}