Esempio n. 1
0
int MPID_Win_free(MPIR_Win ** win_ptr)
{
    int mpi_errno = MPI_SUCCESS;
    int in_use;
    MPIR_Comm *comm_ptr;
    MPIR_Errflag_t errflag = MPIR_ERR_NONE;
    MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_MPID_WIN_FREE);

    MPIR_FUNC_VERBOSE_RMA_ENTER(MPID_STATE_MPID_WIN_FREE);

    MPIR_ERR_CHKANDJUMP(((*win_ptr)->states.access_state != MPIDI_RMA_NONE &&
                         (*win_ptr)->states.access_state != MPIDI_RMA_FENCE_ISSUED &&
                         (*win_ptr)->states.access_state != MPIDI_RMA_FENCE_GRANTED) ||
                        ((*win_ptr)->states.exposure_state != MPIDI_RMA_NONE),
                        mpi_errno, MPI_ERR_RMA_SYNC, "**rmasync");

    /* 1. Here we must wait until all passive locks are released on this target,
     * because for some UNLOCK messages, we do not send ACK back to origin,
     * we must wait until lock is released so that we can free window.
     * 2. We also need to wait until AT completion counter being zero, because
     * this counter is increment everytime we meet a GET-like operation, it is
     * possible that when target entering Win_free, passive epoch is not finished
     * yet and there are still GETs doing on this target.
     * 3. We also need to wait until lock queue becomes empty. It is possible
     * that some lock requests is still waiting in the queue when target is
     * entering Win_free. */
    while ((*win_ptr)->current_lock_type != MPID_LOCK_NONE ||
           (*win_ptr)->at_completion_counter != 0 ||
           (*win_ptr)->target_lock_queue_head != NULL ||
           (*win_ptr)->current_target_lock_data_bytes != 0 || (*win_ptr)->sync_request_cnt != 0) {
        mpi_errno = wait_progress_engine();
        if (mpi_errno != MPI_SUCCESS)
            MPIR_ERR_POP(mpi_errno);
    }

    mpi_errno = MPID_Barrier((*win_ptr)->comm_ptr, &errflag);
    if (mpi_errno)
        MPIR_ERR_POP(mpi_errno);

    /* Free window resources in lower layer. */
    if (MPIDI_CH3U_Win_hooks.win_free != NULL) {
        mpi_errno = MPIDI_CH3U_Win_hooks.win_free(win_ptr);
        if (mpi_errno != MPI_SUCCESS)
            MPIR_ERR_POP(mpi_errno);
    }

    /* dequeue window from the global list */
    MPIR_Assert((*win_ptr)->active == FALSE);
    DL_DELETE(MPIDI_RMA_Win_inactive_list_head, (*win_ptr));

    if (MPIDI_RMA_Win_inactive_list_head == NULL && MPIDI_RMA_Win_active_list_head == NULL) {
        /* this is the last window, de-register RMA progress hook */
        mpi_errno = MPID_Progress_deregister_hook(MPIDI_CH3I_RMA_Progress_hook_id);
        if (mpi_errno != MPI_SUCCESS) {
            MPIR_ERR_POP(mpi_errno);
        }
    }

    comm_ptr = (*win_ptr)->comm_ptr;
    mpi_errno = MPIR_Comm_free_impl(comm_ptr);
    if (mpi_errno)
        MPIR_ERR_POP(mpi_errno);

    if ((*win_ptr)->basic_info_table != NULL)
        MPL_free((*win_ptr)->basic_info_table);
    MPL_free((*win_ptr)->op_pool_start);
    MPL_free((*win_ptr)->target_pool_start);
    MPL_free((*win_ptr)->slots);
    MPL_free((*win_ptr)->target_lock_entry_pool_start);

    MPIR_Assert((*win_ptr)->current_target_lock_data_bytes == 0);

    /* Free the attached buffer for windows created with MPI_Win_allocate() */
    if ((*win_ptr)->create_flavor == MPI_WIN_FLAVOR_ALLOCATE ||
        (*win_ptr)->create_flavor == MPI_WIN_FLAVOR_SHARED) {
        if ((*win_ptr)->shm_allocated == FALSE && (*win_ptr)->size > 0) {
            MPL_free((*win_ptr)->base);
        }
    }

    MPIR_Object_release_ref(*win_ptr, &in_use);
    /* MPI windows don't have reference count semantics, so this should always be true */
    MPIR_Assert(!in_use);
    MPIR_Handle_obj_free(&MPIR_Win_mem, *win_ptr);

  fn_exit:
    MPIR_FUNC_VERBOSE_RMA_EXIT(MPID_STATE_MPID_WIN_FREE);
    return mpi_errno;

  fn_fail:
    goto fn_exit;
}
Esempio n. 2
0
/* Now the functions */
static int intra_Barrier(struct MPIR_COMMUNICATOR *comm)
{
    int rank, size, N2_prev, surfeit;
    int d, dst, src;
    MPI_Status status;

    /* Intialize communicator size */
    (void) MPIR_Comm_size(comm, &size);

#ifdef MPID_Barrier
    if (comm->ADIBarrier) {
        MPID_Barrier(comm->ADIctx, comm);
        return MPI_SUCCESS;
    }
#endif
    /* If there's only one member, this is trivial */
    if (size > 1) {

        /* Initialize collective communicator */
        comm = comm->comm_coll;
        (void) MPIR_Comm_rank(comm, &rank);
        (void) MPIR_Comm_N2_prev(comm, &N2_prev);
        surfeit = size - N2_prev;

        /* Lock for collective operation */
        MPID_THREAD_LOCK(comm->ADIctx, comm);

        /* Perform a combine-like operation */
        if (rank < N2_prev) {
            if (rank < surfeit) {

                /* get the fanin letter from the upper "half" process: */
                dst = N2_prev + rank;

                MPI_Recv((void *) 0, 0, MPI_INT, dst, MPIR_BARRIER_TAG,
                         comm->self, &status);
            }

            /* combine on embedded N2_prev power-of-two processes */
            for (d = 1; d < N2_prev; d <<= 1) {
                dst = (rank ^ d);

                MPI_Sendrecv((void *) 0, 0, MPI_INT, dst, MPIR_BARRIER_TAG,
                             (void *) 0, 0, MPI_INT, dst, MPIR_BARRIER_TAG,
                             comm->self, &status);
            }

            /* fanout data to nodes above N2_prev... */
            if (rank < surfeit) {
                dst = N2_prev + rank;
                MPI_Send((void *) 0, 0, MPI_INT, dst,
                         MPIR_BARRIER_TAG, comm->self);
            }
        } else {
            /* fanin data to power of 2 subset */
            src = rank - N2_prev;
            MPI_Sendrecv((void *) 0, 0, MPI_INT, src, MPIR_BARRIER_TAG,
                         (void *) 0, 0, MPI_INT, src, MPIR_BARRIER_TAG,
                         comm->self, &status);
        }

        /* Unlock for collective operation */
        MPID_THREAD_UNLOCK(comm->ADIctx, comm);

    }
    return (MPI_SUCCESS);
}