Exemple #1
0
int MPI_Win_lock(int lock_type, int rank, int assert, MPI_Win win)
{
    int rc;

    if (MPI_PARAM_CHECK) {
        OMPI_ERR_INIT_FINALIZE(FUNC_NAME);

        if (ompi_win_invalid(win)) {
            return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_WIN, FUNC_NAME);
        } else if (lock_type != MPI_LOCK_EXCLUSIVE &&
                   lock_type != MPI_LOCK_SHARED) {
            return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_LOCKTYPE, FUNC_NAME);
        } else if (ompi_win_peer_invalid(win, rank)) {
            return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_RANK, FUNC_NAME);
        } else if (0 != (assert & ~(MPI_MODE_NOCHECK))) {
            return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_ASSERT, FUNC_NAME);
        } else if (! ompi_win_allow_locks(win)) {
            return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_RMA_SYNC, FUNC_NAME);
        }
    }

    /* NTH: do not bother keeping track of locking MPI_PROC_NULL. */
    if (MPI_PROC_NULL == rank) return MPI_SUCCESS;

    rc = win->w_osc_module->osc_lock(lock_type, rank, assert, win);
    OMPI_ERRHANDLER_RETURN(rc, win, rc, FUNC_NAME);
}
Exemple #2
0
int MPI_Win_set_errhandler(MPI_Win win, MPI_Errhandler errhandler)
{
    MPI_Errhandler tmp;

    OPAL_CR_NOOP_PROGRESS();

    if (MPI_PARAM_CHECK) {
        OMPI_ERR_INIT_FINALIZE(FUNC_NAME);

        if (ompi_win_invalid(win)) {
            return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_WIN,
                                          FUNC_NAME);
        } else if (NULL == errhandler ||
                   MPI_ERRHANDLER_NULL == errhandler ||
                   (OMPI_ERRHANDLER_TYPE_WIN != errhandler->eh_mpi_object_type &&
                    OMPI_ERRHANDLER_TYPE_PREDEFINED != errhandler->eh_mpi_object_type) ) {
            return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_ARG, FUNC_NAME);
        }
    }

    /* Prepare the new error handler */
    OBJ_RETAIN(errhandler);

    OPAL_THREAD_LOCK(&win->w_lock);
    /* Ditch the old errhandler, and decrement its refcount. */
    tmp = win->error_handler;
    win->error_handler = errhandler;
    OBJ_RELEASE(tmp);
    OPAL_THREAD_UNLOCK(&win->w_lock);

    /* All done */
    return MPI_SUCCESS;
}
int MPI_Win_get_errhandler(MPI_Win win, MPI_Errhandler *errhandler)
{
    MPI_Errhandler tmp;

    OPAL_CR_NOOP_PROGRESS();

    if (MPI_PARAM_CHECK) {
        OMPI_ERR_INIT_FINALIZE(FUNC_NAME);
        if (ompi_win_invalid(win)) {
            return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_WIN,
                                          FUNC_NAME);
        } else if (NULL == errhandler) {
            return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_ARG,
                                          FUNC_NAME);
        }
    }

    /* On 64 bits environments we have to make sure the reading of the
       error_handler became atomic. */
    do {
        tmp = win->error_handler;
    } while (!OPAL_ATOMIC_CMPSET_PTR(&(win->error_handler), tmp, tmp));

    /* Retain the errhandler, corresponding to object refcount
       decrease in errhandler_free.c. */
    OBJ_RETAIN(win->error_handler);
    *errhandler = win->error_handler;

    /* All done */
    return MPI_SUCCESS;
}
int MPI_Win_get_name(MPI_Win win, char *win_name, int *resultlen) 
{
    int ret;

    if (MPI_PARAM_CHECK) {
        OMPI_ERR_INIT_FINALIZE(FUNC_NAME);

        if (ompi_win_invalid(win)) {
            return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_WIN, FUNC_NAME);
        } else if (NULL == win_name || NULL == resultlen) {
            return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_ARG, FUNC_NAME);
        }
    }

    OPAL_CR_ENTER_LIBRARY();

    /* Note that MPI-2.1 requires:
       - terminating the string with a \0
       - name[*resultlen] == '\0'
       - and therefore (*resultlen) cannot be > (MPI_MAX_OBJECT_NAME-1)

       The Fortran API version will pad to the right if necessary.

       Note that win->name is guaranteed to be \0-terminated and
       able to completely fit into MPI_MAX_OBJECT_NAME bytes (i.e.,
       name+\0).  ompi_win_get_name() does the Right things. */
    ret = ompi_win_get_name(win, win_name, resultlen);
    OMPI_ERRHANDLER_RETURN(ret, win, ret, FUNC_NAME);
}
Exemple #5
0
int MPI_Compare_and_swap(const void *origin_addr, const void *compare_addr, void *result_addr,
                         MPI_Datatype datatype, int target_rank, MPI_Aint target_disp, MPI_Win win)
{
    int rc;

    if (MPI_PARAM_CHECK) {
        rc = OMPI_SUCCESS;

        OMPI_ERR_INIT_FINALIZE(FUNC_NAME);

        if (ompi_win_invalid(win)) {
            return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_WIN, FUNC_NAME);
        } else if (ompi_win_peer_invalid(win, target_rank) &&
                   (MPI_PROC_NULL != target_rank)) {
            rc = MPI_ERR_RANK;
        } else if ( MPI_WIN_FLAVOR_DYNAMIC != win->w_flavor && target_disp < 0 ) {
            rc = MPI_ERR_DISP;
        } else {
            OMPI_CHECK_DATATYPE_FOR_ONE_SIDED(rc, datatype, 1);
        }
        OMPI_ERRHANDLER_CHECK(rc, win, rc, FUNC_NAME);
    }

    if (MPI_PROC_NULL == target_rank) return MPI_SUCCESS;

    OPAL_CR_ENTER_LIBRARY();

    rc = win->w_osc_module->osc_compare_and_swap(origin_addr, compare_addr, result_addr,
                                                 datatype, target_rank, target_disp, win);
    OMPI_ERRHANDLER_RETURN(rc, win, rc, FUNC_NAME);
}
Exemple #6
0
int MPI_Win_get_info(MPI_Win win, MPI_Info *info_used)
{
    int ret;

    OPAL_CR_NOOP_PROGRESS();

    if (MPI_PARAM_CHECK) {
        OMPI_ERR_INIT_FINALIZE(FUNC_NAME);

        if (ompi_win_invalid(win)) {
            return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_WIN, FUNC_NAME);
        }

        if (NULL == info_used) {
            return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_ARG, FUNC_NAME);
        }
    }

    if (NULL == win->super.s_info) {
/*
 * Setup any defaults if MPI_Win_set_info was never called
 */
	opal_infosubscribe_change_info(win, &MPI_INFO_NULL->super); 	
    }

    (*info_used) = OBJ_NEW(ompi_info_t);
    if (NULL == (*info_used)) {
       return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_NO_MEM, FUNC_NAME);
    }

    ret = opal_info_dup(&win->super.s_info, &(*info_used)->super);

    OMPI_ERRHANDLER_RETURN(ret, win, ret, FUNC_NAME);
}
int MPI_Win_set_errhandler(MPI_Win win, MPI_Errhandler errhandler) 
{
    MPI_Errhandler tmp;

    OPAL_CR_NOOP_PROGRESS();

    if (MPI_PARAM_CHECK) {
        OMPI_ERR_INIT_FINALIZE(FUNC_NAME);

        if (ompi_win_invalid(win)) {
            return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_WIN,
                                          FUNC_NAME);
        } else if (NULL == errhandler ||
                   MPI_ERRHANDLER_NULL == errhandler ||
                   (OMPI_ERRHANDLER_TYPE_WIN != errhandler->eh_mpi_object_type && 
                    OMPI_ERRHANDLER_TYPE_PREDEFINED != errhandler->eh_mpi_object_type) ) {
            return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_ARG, FUNC_NAME);
        }
    }

    /* Prepare the new error handler */
    OBJ_RETAIN(errhandler);

    /* Ditch the old errhandler, and decrement its refcount.  On 64
       bits environments we have to make sure the reading of the
       error_handler became atomic. */
    do {
        tmp = win->error_handler;
    } while (!OPAL_ATOMIC_CMPSET(&(win->error_handler), tmp, errhandler));
    OBJ_RELEASE(tmp);

    /* All done */
    return MPI_SUCCESS;
}
Exemple #8
0
int MPI_Win_complete(MPI_Win win)
{
    int rc;

    if (MPI_PARAM_CHECK) {
        OMPI_ERR_INIT_FINALIZE(FUNC_NAME);

        if (ompi_win_invalid(win)) {
            return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_WIN, FUNC_NAME);
        }
    }

    rc = win->w_osc_module->osc_complete(win);
    OMPI_ERRHANDLER_RETURN(rc, win, rc, FUNC_NAME);
}
Exemple #9
0
int MPI_Win_set_attr(MPI_Win win, int win_keyval, void *attribute_val) 
{
    int ret;

    if (MPI_PARAM_CHECK) {
        OMPI_ERR_INIT_FINALIZE(FUNC_NAME);

        if (ompi_win_invalid(win)) {
	    return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_WIN, FUNC_NAME);
	}
    }

    ret = ompi_attr_set_c(WIN_ATTR, win, &win->w_keyhash, 
                          win_keyval, attribute_val, false, true);
    OMPI_ERRHANDLER_RETURN(ret, win, MPI_ERR_OTHER, FUNC_NAME);  
}
int MPI_Win_delete_attr(MPI_Win win, int win_keyval) 
{
    int ret; 

    if (MPI_PARAM_CHECK) {
        OMPI_ERR_INIT_FINALIZE(FUNC_NAME);

        if (ompi_win_invalid(win)) {
            return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_WIN, FUNC_NAME);
        }
    }

    OPAL_CR_ENTER_LIBRARY();

    ret = ompi_attr_delete(WIN_ATTR, win, win->w_keyhash, win_keyval, 
                           false, true);
    OMPI_ERRHANDLER_RETURN(ret, win, MPI_ERR_OTHER, FUNC_NAME);  
}
Exemple #11
0
int MPI_Win_fence(int assert, MPI_Win win)
{
    int rc;

    if (MPI_PARAM_CHECK) {
        OMPI_ERR_INIT_FINALIZE(FUNC_NAME);

        if (ompi_win_invalid(win)) {
            return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_WIN, FUNC_NAME);
        } else if (0 != (assert & ~(MPI_MODE_NOSTORE | MPI_MODE_NOPUT |
                                    MPI_MODE_NOPRECEDE | MPI_MODE_NOSUCCEED))) {
            return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_ASSERT, FUNC_NAME);
        }
    }

    rc = win->w_osc_module->osc_fence(assert, win);
    OMPI_ERRHANDLER_RETURN(rc, win, rc, FUNC_NAME);
}
Exemple #12
0
int MPI_Rput(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, MPI_Win win, MPI_Request *request)
{
    int rc;

    if (MPI_PARAM_CHECK) {
        rc = OMPI_SUCCESS;

        OMPI_ERR_INIT_FINALIZE(FUNC_NAME);

        if (ompi_win_invalid(win)) {
            return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_WIN, FUNC_NAME);
        } else if (origin_count < 0 || target_count < 0) {
            rc = MPI_ERR_COUNT;
        } else if (ompi_win_peer_invalid(win, target_rank) &&
                   (MPI_PROC_NULL != target_rank)) {
            rc = MPI_ERR_RANK;
        } else if (NULL == target_datatype ||
                   MPI_DATATYPE_NULL == target_datatype) {
            rc = MPI_ERR_TYPE;
        } else if ( target_disp < 0 ) {
            rc = MPI_ERR_DISP;
        } else {
            OMPI_CHECK_DATATYPE_FOR_ONE_SIDED(rc, origin_datatype, origin_count);
            if (OMPI_SUCCESS == rc) {
                OMPI_CHECK_DATATYPE_FOR_ONE_SIDED(rc, target_datatype, target_count);
            }
        }
        OMPI_ERRHANDLER_CHECK(rc, win, rc, FUNC_NAME);
    }

    if (MPI_PROC_NULL == target_rank) {
        *request = &ompi_request_empty;
        return MPI_SUCCESS;
    }

    OPAL_CR_ENTER_LIBRARY();

    rc = win->w_osc_module->osc_rput(origin_addr, origin_count, origin_datatype,
                                     target_rank, target_disp, target_count,
                                     target_datatype, win, request);
    OMPI_ERRHANDLER_RETURN(rc, win, rc, FUNC_NAME);
}
int MPI_Win_set_name(MPI_Win win, char *win_name) 
{
    int ret;

    if (MPI_PARAM_CHECK) {
        OMPI_ERR_INIT_FINALIZE(FUNC_NAME);

        if (ompi_win_invalid(win)) {
            return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_WIN, FUNC_NAME);
        } else if (NULL == win_name) {
            return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_ARG, FUNC_NAME);
        }
    }

    OPAL_CR_ENTER_LIBRARY();

    ret = ompi_win_set_name(win, win_name);
    OMPI_ERRHANDLER_RETURN(ret, win, ret, FUNC_NAME);
}
Exemple #14
0
int MPI_Win_test(MPI_Win win, int *flag) 
{
    int rc;

    if (MPI_PARAM_CHECK) {
        OMPI_ERR_INIT_FINALIZE(FUNC_NAME);

        if (ompi_win_invalid(win)) {
            return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_WIN, FUNC_NAME);
        } else if (0 == (ompi_win_get_mode(win) & OMPI_WIN_POSTED)) {
            return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_RMA_SYNC, FUNC_NAME);
        }
    }

    OPAL_CR_ENTER_LIBRARY();

    rc = win->w_osc_module->osc_test(win, flag);
    OMPI_ERRHANDLER_RETURN(rc, win, rc, FUNC_NAME);
}
Exemple #15
0
int MPI_Win_set_info(MPI_Win win, MPI_Info info)
{
    int ret;

    if (MPI_PARAM_CHECK) {
        OMPI_ERR_INIT_FINALIZE(FUNC_NAME);

        if (ompi_win_invalid(win)) {
            return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_WIN, FUNC_NAME);
        }

        if (NULL == info || MPI_INFO_NULL == info ||
            ompi_info_is_freed(info)) {
            return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_INFO, FUNC_NAME);
        }
    }

    ret = win->w_osc_module->osc_set_info(win, info);
    OMPI_ERRHANDLER_RETURN(ret, win, ret, FUNC_NAME);
}
Exemple #16
0
int MPI_Win_unlock(int rank, MPI_Win win)
{
    int rc;

    if (MPI_PARAM_CHECK) {
        OMPI_ERR_INIT_FINALIZE(FUNC_NAME);

        if (ompi_win_invalid(win)) {
            return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_WIN, FUNC_NAME);
        } else if (ompi_win_peer_invalid(win, rank)) {
            return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_RANK, FUNC_NAME);
        }
    }

    /* NTH: do not bother keeping track of unlocking MPI_PROC_NULL. */
    if (MPI_PROC_NULL == rank) return MPI_SUCCESS;

    rc = win->w_osc_module->osc_unlock(rank, win);
    OMPI_ERRHANDLER_RETURN(rc, win, rc, FUNC_NAME);
}
int MPI_Win_flush_local_all(MPI_Win win)
{
    int ret = MPI_SUCCESS;
    
    /* argument checking */
    if (MPI_PARAM_CHECK) {
        OMPI_ERR_INIT_FINALIZE(FUNC_NAME);

        if (ompi_win_invalid(win)) {
            return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_WIN, FUNC_NAME);
        }
        OMPI_ERRHANDLER_CHECK(ret, win, ret, FUNC_NAME);
    }

    OPAL_CR_ENTER_LIBRARY();

    /* create window and return */
    ret = win->w_osc_module->osc_flush_local_all(win);
    OMPI_ERRHANDLER_RETURN(ret, win, ret, FUNC_NAME);
}
int MPI_Win_call_errhandler(MPI_Win win, int errorcode) 
{

    OPAL_CR_NOOP_PROGRESS();

    if (MPI_PARAM_CHECK) {
        OMPI_ERR_INIT_FINALIZE(FUNC_NAME);

        if (ompi_win_invalid(win)) {
            return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_WIN,
                                          FUNC_NAME);
        }
    }

  /* Invoke the errhandler */
  OMPI_ERRHANDLER_INVOKE(win, errorcode, FUNC_NAME);

  /* See MPI-2 8.5 why this function has to return MPI_SUCCESS */
  return MPI_SUCCESS;
}
int MPI_Get(void *origin_addr, int origin_count,
            MPI_Datatype origin_datatype, int target_rank,
            MPI_Aint target_disp, int target_count,
            MPI_Datatype target_datatype, MPI_Win win)
{
    int rc;

    if (MPI_PARAM_CHECK) {
        rc = OMPI_SUCCESS;

        OMPI_ERR_INIT_FINALIZE(FUNC_NAME);

        if (ompi_win_invalid(win)) {
            return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_WIN, FUNC_NAME);
        } else if (origin_count < 0 || target_count < 0) {
            rc = MPI_ERR_COUNT;
        } else if (ompi_win_peer_invalid(win, target_rank) &&
                   (MPI_PROC_NULL != target_rank)) {
            rc = MPI_ERR_RANK;
        } else if (!ompi_win_comm_allowed(win)) {
            rc = MPI_ERR_RMA_SYNC;
        } else if ( target_disp < 0 ) {
            rc = MPI_ERR_DISP;
        } else if ( (origin_count < 0) || (target_count < 0) ) {
            rc = MPI_ERR_COUNT;
        } else {
            OMPI_CHECK_DATATYPE_FOR_ONE_SIDED(rc, origin_datatype, origin_count);
            if (OMPI_SUCCESS == rc) {
                OMPI_CHECK_DATATYPE_FOR_ONE_SIDED(rc, target_datatype, target_count);
            }
        }
        OMPI_ERRHANDLER_CHECK(rc, win, rc, FUNC_NAME);
    }

    if (MPI_PROC_NULL == target_rank) return MPI_SUCCESS;

    rc = win->w_osc_module->osc_get(origin_addr, origin_count, origin_datatype,
                                    target_rank, target_disp, target_count,
                                    target_datatype, win);
    OMPI_ERRHANDLER_RETURN(rc, win, rc, FUNC_NAME);
}
int MPI_Win_lock_all(int assert, MPI_Win win) 
{
    int rc;

    if (MPI_PARAM_CHECK) {
        OMPI_ERR_INIT_FINALIZE(FUNC_NAME);

        if (ompi_win_invalid(win)) {
            return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_WIN, FUNC_NAME);
        } else if (0 != (assert & ~(MPI_MODE_NOCHECK))) {
            return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_ASSERT, FUNC_NAME);
        } else if (! ompi_win_allow_locks(win)) {
            return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_RMA_SYNC, FUNC_NAME);
        }
    }

    OPAL_CR_ENTER_LIBRARY();

    rc = win->w_osc_module->osc_lock_all(assert, win);
    OMPI_ERRHANDLER_RETURN(rc, win, rc, FUNC_NAME);
}
int MPI_Win_detach(MPI_Win win, void *base)
{
    int ret = MPI_SUCCESS;
    
    /* argument checking */
    if (MPI_PARAM_CHECK) {
        OMPI_ERR_INIT_FINALIZE(FUNC_NAME);

        if (ompi_win_invalid(win)) {
            return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_WIN, FUNC_NAME);
        } else if (NULL == base) {
            ret = MPI_ERR_ARG;
        }
        OMPI_ERRHANDLER_CHECK(ret, win, ret, FUNC_NAME);
    }

    OPAL_CR_ENTER_LIBRARY();

    /* create window and return */
    ret = win->w_osc_module->osc_win_detach(win, base);
    OMPI_ERRHANDLER_RETURN(ret, win, ret, FUNC_NAME);
}
int MPI_Win_get_attr(MPI_Win win, int win_keyval,
                     void *attribute_val, int *flag) 
{
    int ret;

    if (MPI_PARAM_CHECK) {
       OMPI_ERR_INIT_FINALIZE(FUNC_NAME);

       if (ompi_win_invalid(win)) {
           return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_WIN, FUNC_NAME);
       } else if ((NULL == attribute_val) || (NULL == flag)) {
           return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_ARG, FUNC_NAME);
        } else if (MPI_KEYVAL_INVALID == win_keyval) {
            return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_KEYVAL, FUNC_NAME);
       }
    }

    OPAL_CR_ENTER_LIBRARY();

    /* This stuff is very confusing.  Be sure to see
       src/attribute/attribute.c for a lengthy comment explaining Open
       MPI attribute behavior. */

    ret = ompi_attr_get_c(win->w_keyhash, win_keyval, 
                          (void**)attribute_val, flag);

    /* MPI-2 Section 6.2.2 says that for MPI_WIN_BASE, base will be a
       pointer to the window in C/C++ and an integer representation of
       the base address in Fortran.  The only rational way to do this
       is to store a pointer to the pointer in C (so that the
       attribute code will do the right thing in Fortran) and
       dereference the C attribute here so that it's right for C as
       well. */
    if (win_keyval == MPI_WIN_BASE) {
        *((void**) attribute_val) = *((void**) attribute_val);
    }

    OMPI_ERRHANDLER_RETURN(ret, win, MPI_ERR_OTHER, FUNC_NAME);  
}
Exemple #23
0
MPI_Fint MPI_Win_c2f(MPI_Win win)
{

    if ( MPI_PARAM_CHECK) {
        OMPI_ERR_INIT_FINALIZE(FUNC_NAME);

        /* Note that ompi_win_invalid() explicitly checks for
           MPI_WIN_NULL, but MPI_WIN_C2F is supposed to treat
           MPI_WIN_NULL as a valid window (and therefore return
           a valid Fortran handle for it).  Hence, this function
           should not return an error if MPI_WIN_NULL is passed in.

           See a big comment in ompi/communicator/communicator.h about
           this (I know that's not win.h, but the issues are related,
           and that's where the explanation is). */
        if (ompi_win_invalid(win) && MPI_WIN_NULL != win) {
            return OMPI_INT_2_FINT(-1);
        }
    }

    return OMPI_INT_2_FINT(win->w_f_to_c_index);
}
Exemple #24
0
int ompi_win_finalize(void)
{
    size_t size = opal_pointer_array_get_size (&ompi_mpi_windows);
    /* start at 1 to skip win null */
    for (size_t i = 1 ; i < size ; ++i) {
        ompi_win_t *win =
            (ompi_win_t *) opal_pointer_array_get_item (&ompi_mpi_windows, i);
        if (NULL != win) {
            if (ompi_debug_show_handle_leaks && !ompi_win_invalid(win)){
                opal_output(0,"WARNING: MPI_Win still allocated in MPI_Finalize\n");
                ompi_win_dump (win);
            }
            ompi_win_free (win);
        }
    }

    OBJ_DESTRUCT(&ompi_mpi_win_null.win);
    OBJ_DESTRUCT(&ompi_mpi_windows);
    OBJ_RELEASE(ompi_win_accumulate_ops);

    return OMPI_SUCCESS;
}
Exemple #25
0
int MPI_Accumulate(void *origin_addr, int origin_count, MPI_Datatype origin_datatype,
                   int target_rank, MPI_Aint target_disp, int target_count,
                   MPI_Datatype target_datatype, MPI_Op op, MPI_Win win) 
{
    int rc;
    ompi_win_t *ompi_win = (ompi_win_t*) win;

    if (MPI_PARAM_CHECK) {
        rc = OMPI_SUCCESS;

        OMPI_ERR_INIT_FINALIZE(FUNC_NAME);

        if (ompi_win_invalid(win)) {
            return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_WIN, FUNC_NAME);
        } else if (origin_count < 0 || target_count < 0) {
            rc = MPI_ERR_COUNT;
        } else if (ompi_win_peer_invalid(win, target_rank) &&
                   (MPI_PROC_NULL != target_rank)) {
            rc = MPI_ERR_RANK;
        } else if (MPI_OP_NULL == op) {
            rc = MPI_ERR_OP;
        } else if (!ompi_op_is_intrinsic(op)) {
            rc = MPI_ERR_OP;
        } else if (!ompi_win_comm_allowed(win)) {
            rc = MPI_ERR_RMA_SYNC;
        } else if ( target_disp < 0 ) {
            rc = MPI_ERR_DISP;
        } else if ( (origin_count < 0) || (target_count < 0) ) {
            rc = MPI_ERR_COUNT;
        } else {
            OMPI_CHECK_DATATYPE_FOR_ONE_SIDED(rc, origin_datatype, origin_count);
            if (OMPI_SUCCESS == rc) {
                OMPI_CHECK_DATATYPE_FOR_ONE_SIDED(rc, target_datatype, target_count);
            }
            if (OMPI_SUCCESS == rc) {
                /* While technically the standard probably requires that the
                   datatypes used with MPI_REPLACE conform to all the rules
                   for other reduction operators, we don't require such
                   behaivor, as checking for it is expensive here and we don't
                   care in implementation.. */
                if (op != &ompi_mpi_op_replace) {
                    ompi_datatype_t *op_check_dt, *origin_check_dt;
                    char *msg;

                    if (ompi_ddt_is_predefined(origin_datatype)) {
                        origin_check_dt = origin_datatype;
                    } else {
                        int i, index = -1, num_found = 0;
                        uint64_t mask = 1;

                        for (i = 0 ; i < DT_MAX_PREDEFINED ; ++i) {
                            if (origin_datatype->bdt_used & mask) {
                                num_found++;
                                index = i;
                            }
                            mask *= 2;
                        }
                        if (index < 0 || num_found > 1) {
                            /* this is an erroneous datatype.  Let
                               ompi_op_is_valid tell the user that */
                            OMPI_ERRHANDLER_RETURN(MPI_ERR_TYPE, win, MPI_ERR_TYPE, FUNC_NAME);
                        } else {
                            origin_check_dt = (ompi_datatype_t*)
                                ompi_ddt_basicDatatypes[index];
                        }
                    }

                    /* ACCUMULATE, unlike REDUCE, can use with derived
                       datatypes with predefinied operations, with some
                       restrictions outlined in MPI-2:6.3.4.  The derived
                       datatype must be composed entirley from one predefined
                       datatype (so you can do all the construction you want,
                       but at the bottom, you can only use one datatype, say,
                       MPI_INT).  If the datatype at the target isn't
                       predefined, then make sure it's composed of only one
                       datatype, and check that datatype against
                       ompi_op_is_valid(). */
                    if (ompi_ddt_is_predefined(target_datatype)) {
                        op_check_dt = target_datatype;
                    } else {
                        int i, index = -1, num_found = 0;
                        uint64_t mask = 1;

                        for (i = 0 ; i < DT_MAX_PREDEFINED ; ++i) {
                            if (target_datatype->bdt_used & mask) {
                                num_found++;
                                index = i;
                            }
                            mask *= 2;
                        }
                        if (index < 0 || num_found > 1) {
                            /* this is an erroneous datatype.  Let
                               ompi_op_is_valid tell the user that */
                            OMPI_ERRHANDLER_RETURN(MPI_ERR_TYPE, win, MPI_ERR_TYPE, FUNC_NAME);
                        } else {
                            /* datatype passes muster as far as restrictions
                               in MPI-2:6.3.4.  Is the primitive ok with the
                               op?  Unfortunately have to cast away
                               constness... */
                            op_check_dt = (ompi_datatype_t*)
                                ompi_ddt_basicDatatypes[index];
                        }
                    }

                    /* check to make sure same primitive type */
                    if (op_check_dt != origin_check_dt) {
                        OMPI_ERRHANDLER_RETURN(MPI_ERR_ARG, win, MPI_ERR_ARG, FUNC_NAME);
                    }

                    /* check to make sure primitive type is valid for
                       reduction.  Should do this on the target, but
                       then can't get the errcode back for this
                       call */
                    if (!ompi_op_is_valid(op, op_check_dt, &msg, FUNC_NAME)) {
                        int ret = OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_OP, msg);
                        free(msg);
                        return ret;
                    }
                }
            }
        }
        OMPI_ERRHANDLER_CHECK(rc, win, rc, FUNC_NAME);

        /* While technically the standard probably requires that the
           datatypes used with MPI_REPLACE conform to all the rules
           for other reduction operators, we don't require such
           behaivor, as checking for it is expensive here and we don't
           care in implementation.. */
        if (op != &ompi_mpi_op_replace) {
            ompi_datatype_t *op_check_dt;
            char *msg;

            /* ACCUMULATE, unlike REDUCE, can use with derived
               datatypes with predefinied operations, with some
               restrictions outlined in MPI-2:6.3.4.  The derived
               datatype must be composed entirley from one predefined
               datatype (so you can do all the construction you want,
               but at the bottom, you can only use one datatype, say,
               MPI_INT).  If the datatype at the target isn't
               predefined, then make sure it's composed of only one
               datatype, and check that datatype against
               ompi_op_is_valid(). */
            if (ompi_ddt_is_predefined(target_datatype)) {
                op_check_dt = target_datatype;
            } else {
                int i, index = -1, num_found = 0;
                uint64_t mask = 1;

                for (i = 0 ; i < DT_MAX_PREDEFINED ; ++i) {
                    if (target_datatype->bdt_used & mask) {
                        num_found++;
                        index = i;
                    }
                    mask *= 2;
                }
                if (index < 0 || num_found > 1) {
                    /* this is an erroneous datatype.  Let
                       ompi_op_is_valid tell the user that */
                    op_check_dt = target_datatype;
                } else {
                    /* datatype passes muster as far as restrictions
                       in MPI-2:6.3.4.  Is the primitive ok with the
                       op?  Unfortunately have to cast away
                       constness... */
                    op_check_dt = (ompi_datatype_t*)
                        ompi_ddt_basicDatatypes[index];
                }
            }
            if (!ompi_op_is_valid(op, op_check_dt, &msg, FUNC_NAME)) {
                int ret = OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_OP, msg);
                free(msg);
                return ret;
            }
        }
    }

    if (MPI_PROC_NULL == target_rank) return MPI_SUCCESS;

    rc = ompi_win->w_osc_module->osc_accumulate(origin_addr, 
                                                origin_count,
                                                origin_datatype,
                                                target_rank, 
                                                target_disp, 
                                                target_count,
                                                target_datatype, 
                                                op, win);
    OMPI_ERRHANDLER_RETURN(rc, win, rc, FUNC_NAME);
}