mpid_rma.c 13.3 KB
Newer Older
1
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
2 3 4 5 6 7
/*
 *  (C) 2001 by Argonne National Laboratory.
 *      See COPYRIGHT in top-level directory.
 */

#include "mpidimpl.h"
8
#include "mpidrma.h"
9

10 11 12 13 14 15 16 17 18 19 20 21 22

MPIU_THREADSAFE_INIT_DECL(initRMAoptions);
#ifdef USE_MPIU_INSTR
MPIU_INSTR_DURATION_DECL(wincreate_allgather);
MPIU_INSTR_DURATION_DECL(winfree_rs);
MPIU_INSTR_DURATION_DECL(winfree_complete);
MPIU_INSTR_DURATION_DECL(rmaqueue_alloc);
MPIU_INSTR_DURATION_DECL(rmaqueue_set);
extern void MPIDI_CH3_RMA_InitInstr(void);
#endif


static int win_init(MPI_Aint size, int disp_unit, int create_flavor, int model,
23
                    MPID_Comm *comm_ptr, MPID_Win **win_ptr);
24 25


26 27 28
#define MPID_WIN_FTABLE_SET_DEFAULTS(win_ptr)                   \
    do {                                                        \
        /* Get ptr to RMAFns, which is embedded in MPID_Win */  \
29
        MPID_RMAFns *ftable         = &(*(win_ptr))->RMAFns;    \
30
        ftable->Win_free            = MPIDI_Win_free;           \
31 32
        ftable->Win_attach          = MPIDI_Win_attach;         \
        ftable->Win_detach          = MPIDI_Win_detach;         \
33 34
        ftable->Win_shared_query    = MPIDI_Win_shared_query;   \
                                                                \
35 36 37
        ftable->Win_set_info        = MPIDI_Win_set_info;       \
        ftable->Win_get_info        = MPIDI_Win_get_info;       \
                                                                \
38 39 40
        ftable->Put                 = MPIDI_Put;                \
        ftable->Get                 = MPIDI_Get;                \
        ftable->Accumulate          = MPIDI_Accumulate;         \
41 42 43
        ftable->Get_accumulate      = MPIDI_Get_accumulate;     \
        ftable->Fetch_and_op        = MPIDI_Fetch_and_op;       \
        ftable->Compare_and_swap    = MPIDI_Compare_and_swap;   \
44
                                                                \
45 46 47 48
        ftable->Rput                = MPIDI_Rput;               \
        ftable->Rget                = MPIDI_Rget;               \
        ftable->Raccumulate         = MPIDI_Raccumulate;        \
        ftable->Rget_accumulate     = MPIDI_Rget_accumulate;    \
49 50 51 52 53 54 55 56 57 58 59 60 61
                                                                \
        ftable->Win_fence           = MPIDI_Win_fence;          \
        ftable->Win_post            = MPIDI_Win_post;           \
        ftable->Win_start           = MPIDI_Win_start;          \
        ftable->Win_complete        = MPIDI_Win_complete;       \
        ftable->Win_wait            = MPIDI_Win_wait;           \
        ftable->Win_test            = MPIDI_Win_test;           \
                                                                \
        ftable->Win_lock            = MPIDI_Win_lock;           \
        ftable->Win_unlock          = MPIDI_Win_unlock;         \
        ftable->Win_lock_all        = MPIDI_Win_lock_all;       \
        ftable->Win_unlock_all      = MPIDI_Win_unlock_all;     \
                                                                \
62 63 64 65
        ftable->Win_flush           = MPIDI_Win_flush;          \
        ftable->Win_flush_all       = MPIDI_Win_flush_all;      \
        ftable->Win_flush_local     = MPIDI_Win_flush_local;    \
        ftable->Win_flush_local_all = MPIDI_Win_flush_local_all;\
66 67 68 69
        ftable->Win_sync            = MPIDI_Win_sync;           \
    } while (0)


70
#undef FUNCNAME
71
#define FUNCNAME MPID_Win_create
72 73 74 75 76 77
#undef FCNAME
#define FCNAME MPIDI_QUOTE(FUNCNAME)
int MPID_Win_create(void *base, MPI_Aint size, int disp_unit, MPID_Info *info, 
                    MPID_Comm *comm_ptr, MPID_Win **win_ptr)
{
    int mpi_errno=MPI_SUCCESS;
78

79 80 81 82
    MPIDI_STATE_DECL(MPID_STATE_MPID_WIN_CREATE);
    
    MPIDI_RMA_FUNC_ENTER(MPID_STATE_MPID_WIN_CREATE);

83
    mpi_errno = win_init(size, disp_unit, MPI_WIN_FLAVOR_CREATE, MPI_WIN_UNIFIED, comm_ptr, win_ptr);
84
    if (mpi_errno) MPIU_ERR_POP(mpi_errno);
85

86 87 88 89
    (*win_ptr)->base = base;

    mpi_errno = MPIDI_CH3U_Win_fns.create(base, size, disp_unit, info, comm_ptr, win_ptr); 
    if (mpi_errno) MPIU_ERR_POP(mpi_errno);
90 91 92 93 94 95 96 97 98 99 100 101 102 103

 fn_fail:
    MPIDI_FUNC_EXIT(MPID_STATE_MPID_WIN_CREATE);
    return mpi_errno;
}


#undef FUNCNAME
#define FUNCNAME MPID_Win_allocate
#undef FCNAME
#define FCNAME MPIDI_QUOTE(FUNCNAME)
int MPID_Win_allocate(MPI_Aint size, int disp_unit, MPID_Info *info, 
                    MPID_Comm *comm_ptr, void *baseptr, MPID_Win **win_ptr)
{
104
    int mpi_errno = MPI_SUCCESS;
105 106 107 108
    MPIDI_STATE_DECL(MPID_STATE_MPID_WIN_ALLOCATE);
    
    MPIDI_RMA_FUNC_ENTER(MPID_STATE_MPID_WIN_ALLOCATE);

109
    mpi_errno = win_init(size, disp_unit, MPI_WIN_FLAVOR_ALLOCATE, MPI_WIN_UNIFIED, comm_ptr, win_ptr);
110
    if (mpi_errno != MPI_SUCCESS) { MPIU_ERR_POP(mpi_errno); }
111

112 113 114
    /* FOR ALLOCATE, alloc_shm info is default to set to TRUE */
    (*win_ptr)->info_args.alloc_shm = TRUE;

115 116 117 118
    if (info != NULL) {
        int alloc_shm_flag = 0;
        char shm_alloc_value[MPI_MAX_INFO_VAL+1];
        MPIR_Info_get_impl(info, "alloc_shm", MPI_MAX_INFO_VAL, shm_alloc_value, &alloc_shm_flag);
119 120
        if ((alloc_shm_flag == 1) && (!strncmp(shm_alloc_value, "false", sizeof("false"))))
            (*win_ptr)->info_args.alloc_shm = FALSE;
121 122
    }

123 124
    mpi_errno = MPIDI_CH3U_Win_fns.allocate(size, disp_unit, info, comm_ptr, baseptr, win_ptr);
    if (mpi_errno != MPI_SUCCESS) { MPIU_ERR_POP(mpi_errno); }
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140

 fn_fail:
    MPIDI_FUNC_EXIT(MPID_STATE_MPID_WIN_ALLOCATE);
    return mpi_errno;
}


#undef FUNCNAME
#define FUNCNAME MPID_Win_create_dynamic
#undef FCNAME
#define FCNAME MPIDI_QUOTE(FUNCNAME)
int MPID_Win_create_dynamic(MPID_Info *info, MPID_Comm *comm_ptr,
                            MPID_Win **win_ptr)
{
    int mpi_errno=MPI_SUCCESS;

141
    MPIDI_STATE_DECL(MPID_STATE_MPID_WIN_CREATE_DYNAMIC);
142

143
    MPIDI_RMA_FUNC_ENTER(MPID_STATE_MPID_WIN_CREATE_DYNAMIC);
144

145 146
    mpi_errno = win_init(0 /* spec defines size to be 0 */,
                         1 /* spec defines disp_unit to be 1 */,
147
                         MPI_WIN_FLAVOR_DYNAMIC, MPI_WIN_UNIFIED,
148 149
                         comm_ptr, win_ptr);

150
    if (mpi_errno) MPIU_ERR_POP(mpi_errno);
151

152 153
    (*win_ptr)->base = MPI_BOTTOM;

154 155
    mpi_errno = MPIDI_CH3U_Win_fns.create_dynamic(info, comm_ptr, win_ptr);
    if (mpi_errno != MPI_SUCCESS) { MPIU_ERR_POP(mpi_errno); }
156 157

 fn_fail:
158
    MPIDI_FUNC_EXIT(MPID_STATE_MPID_WIN_CREATE_DYNAMIC);
159 160 161 162
    return mpi_errno;
}


163
/* The memory allocation functions */
164 165 166 167 168 169 170 171 172 173 174
#undef FUNCNAME
#define FUNCNAME MPID_Alloc_mem
#undef FCNAME
#define FCNAME MPIDI_QUOTE(FUNCNAME)
void *MPID_Alloc_mem( size_t size, MPID_Info *info_ptr )
{
    void *ap=NULL;
    MPIDI_STATE_DECL(MPID_STATE_MPID_ALLOC_MEM);

    MPIDI_FUNC_ENTER(MPID_STATE_MPID_ALLOC_MEM);

175
    ap = MPIDI_Alloc_mem(size, info_ptr);
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
    
    MPIDI_FUNC_EXIT(MPID_STATE_MPID_ALLOC_MEM);
    return ap;
}


#undef FUNCNAME
#define FUNCNAME MPID_Free_mem
#undef FCNAME
#define FCNAME MPIDI_QUOTE(FUNCNAME)
int MPID_Free_mem( void *ptr )
{
    int mpi_errno = MPI_SUCCESS;
    MPIDI_STATE_DECL(MPID_STATE_MPID_FREE_MEM);

    MPIDI_FUNC_ENTER(MPID_STATE_MPID_FREE_MEM);

193
    mpi_errno = MPIDI_Free_mem(ptr);
194 195
    if (mpi_errno != MPI_SUCCESS) {
	MPIU_ERR_POP(mpi_errno);
196
    }
197
        
198
 fn_fail:
199
    MPIDI_FUNC_EXIT(MPID_STATE_MPID_FREE_MEM);
200 201 202
    return mpi_errno;
}

203

204 205 206 207
#undef FUNCNAME
#define FUNCNAME MPID_Win_allocate_shared
#undef FCNAME
#define FCNAME MPIDI_QUOTE(FUNCNAME)
208
int MPID_Win_allocate_shared(MPI_Aint size, int disp_unit, MPID_Info *info, MPID_Comm *comm_ptr,
209 210 211 212 213 214 215 216
                             void **base_ptr, MPID_Win **win_ptr)
{
    int mpi_errno=MPI_SUCCESS;

    MPIDI_STATE_DECL(MPID_STATE_MPID_WIN_ALLOCATE_SHARED);
    
    MPIDI_RMA_FUNC_ENTER(MPID_STATE_MPID_WIN_ALLOCATE_SHARED);

217
    mpi_errno = win_init(size, disp_unit, MPI_WIN_FLAVOR_SHARED, MPI_WIN_UNIFIED, comm_ptr, win_ptr);
218 219
    if (mpi_errno) MPIU_ERR_POP(mpi_errno);

220 221 222 223 224 225 226 227 228 229 230 231
    /* FOR ALLOCATE_SHARED, alloc_shm info is default to set to TRUE */
    (*win_ptr)->info_args.alloc_shm = TRUE;

    if (info != NULL) {
        int alloc_shm_flag = 0;
        char shm_alloc_value[MPI_MAX_INFO_VAL+1];
        MPIR_Info_get_impl(info, "alloc_shm", MPI_MAX_INFO_VAL, shm_alloc_value, &alloc_shm_flag);
        /* if value of 'alloc_shm' info is not set to true, throw an error */
        if (alloc_shm_flag == 1 && strncmp(shm_alloc_value, "true", sizeof("true")))
            MPIU_ERR_SETANDJUMP(mpi_errno, MPI_ERR_OTHER, "**infoval");
    }

232
    mpi_errno = MPIDI_CH3U_Win_fns.allocate_shared(size, disp_unit, info, comm_ptr, base_ptr, win_ptr);
233
    if (mpi_errno != MPI_SUCCESS) MPIU_ERR_POP(mpi_errno);
234 235 236 237 238

 fn_fail:
    MPIDI_FUNC_EXIT(MPID_STATE_MPID_WIN_ALLOCATE_SHARED);
    return mpi_errno;
}
239 240 241 242 243 244 245


#undef FUNCNAME
#define FUNCNAME win_init
#undef FCNAME
#define FCNAME MPIU_QUOTE(FUNCNAME)
static int win_init(MPI_Aint size, int disp_unit, int create_flavor, int model,
246
                          MPID_Comm *comm_ptr, MPID_Win **win_ptr)
247 248
{
    int mpi_errno = MPI_SUCCESS;
249
    int i;
250
    MPID_Comm *win_comm_ptr;
251
    MPIU_CHKPMEM_DECL(1);
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280
    MPIDI_STATE_DECL(MPID_STATE_WIN_INIT);

    MPIDI_FUNC_ENTER(MPID_STATE_WIN_INIT);

    if(initRMAoptions) {
        MPIU_THREADSAFE_INIT_BLOCK_BEGIN(initRMAoptions);
#ifdef USE_MPIU_INSTR
        /* Define all instrumentation handles used in the CH3 RMA here*/
        MPIU_INSTR_DURATION_INIT(wincreate_allgather,0,"WIN_CREATE:Allgather");
        MPIU_INSTR_DURATION_INIT(winfree_rs,0,"WIN_FREE:ReduceScatterBlock");
        MPIU_INSTR_DURATION_INIT(winfree_complete,0,"WIN_FREE:Complete");
        MPIU_INSTR_DURATION_INIT(rmaqueue_alloc,0,"Allocate RMA Queue element");
        MPIU_INSTR_DURATION_INIT(rmaqueue_set,0,"Set fields in RMA Queue element");
        MPIDI_CH3_RMA_InitInstr();
#endif

        MPIU_THREADSAFE_INIT_CLEAR(initRMAoptions);
        MPIU_THREADSAFE_INIT_BLOCK_END(initRMAoptions);
    }

    *win_ptr = (MPID_Win *)MPIU_Handle_obj_alloc( &MPID_Win_mem );
    MPIU_ERR_CHKANDJUMP1(!(*win_ptr),mpi_errno,MPI_ERR_OTHER,"**nomem",
                         "**nomem %s","MPID_Win_mem");

    mpi_errno = MPIR_Comm_dup_impl(comm_ptr, &win_comm_ptr);
    if (mpi_errno) MPIU_ERR_POP(mpi_errno);

    MPIU_Object_set_ref(*win_ptr, 1);

281
    (*win_ptr)->fence_issued        = 0;
282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302
    /* (*win_ptr)->errhandler is set by upper level; */
    /* (*win_ptr)->base is set by caller; */
    (*win_ptr)->size                = size;
    (*win_ptr)->disp_unit           = disp_unit;
    (*win_ptr)->create_flavor       = create_flavor;
    (*win_ptr)->model               = model;
    (*win_ptr)->attributes          = NULL;
    (*win_ptr)->start_group_ptr     = NULL;
    (*win_ptr)->start_assert        = 0;
    (*win_ptr)->comm_ptr            = win_comm_ptr;

    (*win_ptr)->my_counter          = 0;
    /* (*win_ptr)->base_addrs[] is set by caller; */
    /* (*win_ptr)->sizes[] is set by caller; */
    /* (*win_ptr)->disp_units[] is set by caller; */
    /* (*win_ptr)->all_win_handles[] is set by caller; */
    (*win_ptr)->current_lock_type   = MPID_LOCK_NONE;
    (*win_ptr)->shared_lock_ref_cnt = 0;
    (*win_ptr)->lock_queue          = NULL;
    (*win_ptr)->pt_rma_puts_accs    = NULL;
    (*win_ptr)->my_pt_rma_puts_accs = 0;
James Dinan's avatar
James Dinan committed
303 304
    (*win_ptr)->epoch_state         = MPIDI_EPOCH_NONE;
    (*win_ptr)->epoch_count         = 0;
305
    (*win_ptr)->at_rma_ops_list     = NULL;
306
    (*win_ptr)->shm_allocated       = FALSE;
307

308
    /* Initialize the passive target lock state */
309 310
    MPIU_CHKPMEM_MALLOC((*win_ptr)->targets, struct MPIDI_Win_target_state *,
                        sizeof(struct MPIDI_Win_target_state)*MPIR_Comm_size(win_comm_ptr),
311 312 313 314
                        mpi_errno, "RMA target states array");

    for (i = 0; i < MPIR_Comm_size(win_comm_ptr); i++) {
        (*win_ptr)->targets[i].rma_ops_list = NULL;
315
        (*win_ptr)->targets[i].remote_lock_state = MPIDI_CH3_WIN_LOCK_NONE;
316 317
    }

318 319 320 321 322 323 324
    /* Initialize the info flags */
    (*win_ptr)->info_args.no_locks            = 0;
    (*win_ptr)->info_args.accumulate_ordering = MPIDI_ACC_ORDER_RAR | MPIDI_ACC_ORDER_RAW |
                                                MPIDI_ACC_ORDER_WAR | MPIDI_ACC_ORDER_WAW;
    (*win_ptr)->info_args.accumulate_ops      = MPIDI_ACC_OPS_SAME_OP_NO_OP;
    (*win_ptr)->info_args.same_size           = 0;
    (*win_ptr)->info_args.alloc_shared_noncontig = 0;
325
    (*win_ptr)->info_args.alloc_shm = FALSE;
326

327 328 329 330 331 332
    MPID_WIN_FTABLE_SET_DEFAULTS(win_ptr);

fn_exit:
    MPIDI_FUNC_EXIT(MPID_STATE_WIN_INIT);
    return mpi_errno;
fn_fail:
333
    MPIU_CHKPMEM_REAP();
334 335
    goto fn_exit;
}
336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379


#undef FUNCNAME
#define FUNCNAME MPID_Win_set_info
#undef FCNAME
#define FCNAME MPIDI_QUOTE(FUNCNAME)
int MPID_Win_set_info(MPID_Win *win, MPID_Info *info)
{
    int mpi_errno = MPI_SUCCESS;
    MPIDI_STATE_DECL(MPID_STATE_MPID_WIN_SET_INFO);

    MPIDI_FUNC_ENTER(MPID_STATE_MPID_WIN_SET_INFO);

    mpi_errno = win->RMAFns.Win_set_info(win, info);
    if (mpi_errno != MPI_SUCCESS) { MPIU_ERR_POP(mpi_errno); }

 fn_exit:
    MPIDI_FUNC_EXIT(MPID_STATE_MPID_WIN_SET_INFO);
    return mpi_errno;
 fn_fail:
    goto fn_exit;
}


#undef FUNCNAME
#define FUNCNAME MPID_Win_get_info
#undef FCNAME
#define FCNAME MPIDI_QUOTE(FUNCNAME)
int MPID_Win_get_info(MPID_Win *win, MPID_Info **info_used)
{
    int mpi_errno = MPI_SUCCESS;
    MPIDI_STATE_DECL(MPID_STATE_MPID_WIN_GET_INFO);

    MPIDI_FUNC_ENTER(MPID_STATE_MPID_WIN_GET_INFO);

    mpi_errno = win->RMAFns.Win_get_info(win, info_used);
    if (mpi_errno != MPI_SUCCESS) { MPIU_ERR_POP(mpi_errno); }

 fn_exit:
    MPIDI_FUNC_EXIT(MPID_STATE_MPID_WIN_GET_INFO);
    return mpi_errno;
 fn_fail:
    goto fn_exit;
}