mpid_rma.c 14.8 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

Xin Zhao's avatar
Xin Zhao committed
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
/*
=== BEGIN_MPI_T_CVAR_INFO_BLOCK ===

cvars:
    - name        : MPIR_CVAR_CH3_RMA_SLOTS_SIZE
      category    : CH3
      type        : int
      default     : 262144
      class       : none
      verbosity   : MPI_T_VERBOSITY_USER_BASIC
      scope       : MPI_T_SCOPE_ALL_EQ
      description : >-
        Number of RMA slots during window creation. Each slot contains
        a linked list of target elements. The distribution of ranks among
        slots follows a round-robin pattern. Requires a positive value.

=== END_MPI_T_CVAR_INFO_BLOCK ===
*/

29 30 31 32

MPIU_THREADSAFE_INIT_DECL(initRMAoptions);

static int win_init(MPI_Aint size, int disp_unit, int create_flavor, int model,
33
                    MPID_Comm * comm_ptr, MPID_Win ** win_ptr);
34 35


36 37 38
#define MPID_WIN_FTABLE_SET_DEFAULTS(win_ptr)                   \
    do {                                                        \
        /* Get ptr to RMAFns, which is embedded in MPID_Win */  \
39
        MPID_RMAFns *ftable         = &(*(win_ptr))->RMAFns;    \
40
        ftable->Win_free            = MPIDI_Win_free;           \
41 42
        ftable->Win_attach          = MPIDI_Win_attach;         \
        ftable->Win_detach          = MPIDI_Win_detach;         \
43 44
        ftable->Win_shared_query    = MPIDI_Win_shared_query;   \
                                                                \
45 46 47
        ftable->Win_set_info        = MPIDI_Win_set_info;       \
        ftable->Win_get_info        = MPIDI_Win_get_info;       \
                                                                \
48 49 50
        ftable->Put                 = MPIDI_Put;                \
        ftable->Get                 = MPIDI_Get;                \
        ftable->Accumulate          = MPIDI_Accumulate;         \
51 52 53
        ftable->Get_accumulate      = MPIDI_Get_accumulate;     \
        ftable->Fetch_and_op        = MPIDI_Fetch_and_op;       \
        ftable->Compare_and_swap    = MPIDI_Compare_and_swap;   \
54
                                                                \
55 56 57 58
        ftable->Rput                = MPIDI_Rput;               \
        ftable->Rget                = MPIDI_Rget;               \
        ftable->Raccumulate         = MPIDI_Raccumulate;        \
        ftable->Rget_accumulate     = MPIDI_Rget_accumulate;    \
59 60 61 62 63 64 65 66 67 68 69 70 71
                                                                \
        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;     \
                                                                \
72 73 74 75
        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;\
76 77 78 79
        ftable->Win_sync            = MPIDI_Win_sync;           \
    } while (0)


80
#undef FUNCNAME
81
#define FUNCNAME MPID_Win_create
82 83
#undef FCNAME
#define FCNAME MPIDI_QUOTE(FUNCNAME)
84 85
int MPID_Win_create(void *base, MPI_Aint size, int disp_unit, MPID_Info * info,
                    MPID_Comm * comm_ptr, MPID_Win ** win_ptr)
86
{
87
    int mpi_errno = MPI_SUCCESS;
88

89
    MPIDI_STATE_DECL(MPID_STATE_MPID_WIN_CREATE);
90

91 92
    MPIDI_RMA_FUNC_ENTER(MPID_STATE_MPID_WIN_CREATE);

Wesley Bland's avatar
Wesley Bland committed
93 94
    /* Check to make sure the communicator hasn't already been revoked */
    if (comm_ptr->revoked) {
95
        MPIU_ERR_SETANDJUMP(mpi_errno, MPIX_ERR_REVOKED, "**revoked");
Wesley Bland's avatar
Wesley Bland committed
96 97
    }

98 99 100 101
    mpi_errno =
        win_init(size, disp_unit, MPI_WIN_FLAVOR_CREATE, MPI_WIN_UNIFIED, comm_ptr, win_ptr);
    if (mpi_errno)
        MPIU_ERR_POP(mpi_errno);
102

103 104
    (*win_ptr)->base = base;

105 106 107
    mpi_errno = MPIDI_CH3U_Win_fns.create(base, size, disp_unit, info, comm_ptr, win_ptr);
    if (mpi_errno)
        MPIU_ERR_POP(mpi_errno);
108

109
  fn_fail:
110 111 112 113 114 115 116 117 118
    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)
119 120
int MPID_Win_allocate(MPI_Aint size, int disp_unit, MPID_Info * info,
                      MPID_Comm * comm_ptr, void *baseptr, MPID_Win ** win_ptr)
121
{
122
    int mpi_errno = MPI_SUCCESS;
123
    MPIDI_STATE_DECL(MPID_STATE_MPID_WIN_ALLOCATE);
124

125 126
    MPIDI_RMA_FUNC_ENTER(MPID_STATE_MPID_WIN_ALLOCATE);

127 128 129 130 131
    mpi_errno =
        win_init(size, disp_unit, MPI_WIN_FLAVOR_ALLOCATE, MPI_WIN_UNIFIED, comm_ptr, win_ptr);
    if (mpi_errno != MPI_SUCCESS) {
        MPIU_ERR_POP(mpi_errno);
    }
132

133 134 135
    /* FOR ALLOCATE, alloc_shm info is default to set to TRUE */
    (*win_ptr)->info_args.alloc_shm = TRUE;

136 137
    if (info != NULL) {
        int alloc_shm_flag = 0;
138
        char shm_alloc_value[MPI_MAX_INFO_VAL + 1];
139
        MPIR_Info_get_impl(info, "alloc_shm", MPI_MAX_INFO_VAL, shm_alloc_value, &alloc_shm_flag);
140 141
        if ((alloc_shm_flag == 1) && (!strncmp(shm_alloc_value, "false", sizeof("false"))))
            (*win_ptr)->info_args.alloc_shm = FALSE;
142 143
    }

144
    mpi_errno = MPIDI_CH3U_Win_fns.allocate(size, disp_unit, info, comm_ptr, baseptr, win_ptr);
145 146 147
    if (mpi_errno != MPI_SUCCESS) {
        MPIU_ERR_POP(mpi_errno);
    }
148

149
  fn_fail:
150 151 152 153 154 155 156 157 158
    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)
159
int MPID_Win_create_dynamic(MPID_Info * info, MPID_Comm * comm_ptr, MPID_Win ** win_ptr)
160
{
161
    int mpi_errno = MPI_SUCCESS;
162

163
    MPIDI_STATE_DECL(MPID_STATE_MPID_WIN_CREATE_DYNAMIC);
164

165
    MPIDI_RMA_FUNC_ENTER(MPID_STATE_MPID_WIN_CREATE_DYNAMIC);
166

167 168 169
    mpi_errno = win_init(0 /* spec defines size to be 0 */ ,
                         1 /* spec defines disp_unit to be 1 */ ,
                         MPI_WIN_FLAVOR_DYNAMIC, MPI_WIN_UNIFIED, comm_ptr, win_ptr);
170

171 172
    if (mpi_errno)
        MPIU_ERR_POP(mpi_errno);
173

174 175
    (*win_ptr)->base = MPI_BOTTOM;

176
    mpi_errno = MPIDI_CH3U_Win_fns.create_dynamic(info, comm_ptr, win_ptr);
177 178 179
    if (mpi_errno != MPI_SUCCESS) {
        MPIU_ERR_POP(mpi_errno);
    }
180

181
  fn_fail:
182
    MPIDI_FUNC_EXIT(MPID_STATE_MPID_WIN_CREATE_DYNAMIC);
183 184 185 186
    return mpi_errno;
}


187
/* The memory allocation functions */
188 189 190 191
#undef FUNCNAME
#define FUNCNAME MPID_Alloc_mem
#undef FCNAME
#define FCNAME MPIDI_QUOTE(FUNCNAME)
192
void *MPID_Alloc_mem(size_t size, MPID_Info * info_ptr)
193
{
194
    void *ap = NULL;
195 196 197 198
    MPIDI_STATE_DECL(MPID_STATE_MPID_ALLOC_MEM);

    MPIDI_FUNC_ENTER(MPID_STATE_MPID_ALLOC_MEM);

199
    ap = MPIDI_Alloc_mem(size, info_ptr);
200

201 202 203 204 205 206 207 208 209
    MPIDI_FUNC_EXIT(MPID_STATE_MPID_ALLOC_MEM);
    return ap;
}


#undef FUNCNAME
#define FUNCNAME MPID_Free_mem
#undef FCNAME
#define FCNAME MPIDI_QUOTE(FUNCNAME)
210
int MPID_Free_mem(void *ptr)
211 212 213 214 215 216
{
    int mpi_errno = MPI_SUCCESS;
    MPIDI_STATE_DECL(MPID_STATE_MPID_FREE_MEM);

    MPIDI_FUNC_ENTER(MPID_STATE_MPID_FREE_MEM);

217
    mpi_errno = MPIDI_Free_mem(ptr);
218
    if (mpi_errno != MPI_SUCCESS) {
219
        MPIU_ERR_POP(mpi_errno);
220
    }
221 222

  fn_fail:
223
    MPIDI_FUNC_EXIT(MPID_STATE_MPID_FREE_MEM);
224 225 226
    return mpi_errno;
}

227

228 229 230 231
#undef FUNCNAME
#define FUNCNAME MPID_Win_allocate_shared
#undef FCNAME
#define FCNAME MPIDI_QUOTE(FUNCNAME)
232 233
int MPID_Win_allocate_shared(MPI_Aint size, int disp_unit, MPID_Info * info, MPID_Comm * comm_ptr,
                             void *base_ptr, MPID_Win ** win_ptr)
234
{
235
    int mpi_errno = MPI_SUCCESS;
236 237

    MPIDI_STATE_DECL(MPID_STATE_MPID_WIN_ALLOCATE_SHARED);
238

239 240
    MPIDI_RMA_FUNC_ENTER(MPID_STATE_MPID_WIN_ALLOCATE_SHARED);

241 242 243 244
    mpi_errno =
        win_init(size, disp_unit, MPI_WIN_FLAVOR_SHARED, MPI_WIN_UNIFIED, comm_ptr, win_ptr);
    if (mpi_errno)
        MPIU_ERR_POP(mpi_errno);
245

246 247 248 249 250
    /* 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;
251
        char shm_alloc_value[MPI_MAX_INFO_VAL + 1];
252 253 254 255 256 257
        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");
    }

258 259 260 261
    mpi_errno =
        MPIDI_CH3U_Win_fns.allocate_shared(size, disp_unit, info, comm_ptr, base_ptr, win_ptr);
    if (mpi_errno != MPI_SUCCESS)
        MPIU_ERR_POP(mpi_errno);
262

263
  fn_fail:
264 265 266
    MPIDI_FUNC_EXIT(MPID_STATE_MPID_WIN_ALLOCATE_SHARED);
    return mpi_errno;
}
267 268 269 270 271 272 273


#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,
274
                    MPID_Comm * comm_ptr, MPID_Win ** win_ptr)
275 276
{
    int mpi_errno = MPI_SUCCESS;
277
    int i;
278
    MPID_Comm *win_comm_ptr;
279
    int win_target_pool_size;
Xin Zhao's avatar
Xin Zhao committed
280
    MPIU_CHKPMEM_DECL(4);
281 282 283 284
    MPIDI_STATE_DECL(MPID_STATE_WIN_INIT);

    MPIDI_FUNC_ENTER(MPID_STATE_WIN_INIT);

285
    if (initRMAoptions) {
286
        MPIU_THREADSAFE_INIT_BLOCK_BEGIN(initRMAoptions);
287 288

        MPIDI_CH3_RMA_Init_Pvars();
289 290 291 292 293

        MPIU_THREADSAFE_INIT_CLEAR(initRMAoptions);
        MPIU_THREADSAFE_INIT_BLOCK_END(initRMAoptions);
    }

294 295 296
    *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");
297 298

    mpi_errno = MPIR_Comm_dup_impl(comm_ptr, &win_comm_ptr);
299 300
    if (mpi_errno)
        MPIU_ERR_POP(mpi_errno);
301 302 303

    MPIU_Object_set_ref(*win_ptr, 1);

304
    (*win_ptr)->fence_issued = 0;
305 306
    /* (*win_ptr)->errhandler is set by upper level; */
    /* (*win_ptr)->base is set by caller; */
307 308 309 310 311 312 313 314
    (*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;
315

316
    (*win_ptr)->at_completion_counter = 0;
317 318 319 320
    /* (*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; */
321
    (*win_ptr)->current_lock_type = MPID_LOCK_NONE;
322
    (*win_ptr)->shared_lock_ref_cnt = 0;
323 324 325 326
    (*win_ptr)->lock_queue = NULL;
    (*win_ptr)->epoch_state = MPIDI_EPOCH_NONE;
    (*win_ptr)->epoch_count = 0;
    (*win_ptr)->at_rma_ops_list = NULL;
327
    (*win_ptr)->at_rma_ops_list_tail = NULL;
328
    (*win_ptr)->shm_allocated = FALSE;
329

330
    /* Initialize the passive target lock state */
331
    MPIU_CHKPMEM_MALLOC((*win_ptr)->targets, struct MPIDI_Win_target_state *,
332
                        sizeof(struct MPIDI_Win_target_state) * MPIR_Comm_size(win_comm_ptr),
333 334 335 336
                        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;
337
        (*win_ptr)->targets[i].rma_ops_list_tail = NULL;
338
        (*win_ptr)->targets[i].remote_lock_state = MPIDI_CH3_WIN_LOCK_NONE;
339 340
    }

341
    /* Initialize the info flags */
342
    (*win_ptr)->info_args.no_locks = 0;
343
    (*win_ptr)->info_args.accumulate_ordering = MPIDI_ACC_ORDER_RAR | MPIDI_ACC_ORDER_RAW |
344 345 346
        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;
347
    (*win_ptr)->info_args.alloc_shared_noncontig = 0;
348
    (*win_ptr)->info_args.alloc_shm = FALSE;
349

350 351 352 353 354 355 356 357 358 359
    MPIU_CHKPMEM_MALLOC((*win_ptr)->op_pool_start, struct MPIDI_RMA_Op *,
                        sizeof(MPIDI_RMA_Op_t) * MPIR_CVAR_CH3_RMA_OP_WIN_POOL_SIZE, mpi_errno,
                        "RMA op pool");
    (*win_ptr)->op_pool = NULL;
    (*win_ptr)->op_pool_tail = NULL;
    for (i = 0; i < MPIR_CVAR_CH3_RMA_OP_WIN_POOL_SIZE; i++) {
        (*win_ptr)->op_pool_start[i].pool_type = MPIDI_RMA_POOL_WIN;
        MPL_LL_APPEND((*win_ptr)->op_pool, (*win_ptr)->op_pool_tail, &((*win_ptr)->op_pool_start[i]));
    }

360 361 362 363 364 365 366 367 368 369 370
    win_target_pool_size = MPIR_MIN(MPIR_CVAR_CH3_RMA_TARGET_WIN_POOL_SIZE, MPIR_Comm_size(win_comm_ptr));
    MPIU_CHKPMEM_MALLOC((*win_ptr)->target_pool_start, struct MPIDI_RMA_Target *,
                        sizeof(MPIDI_RMA_Target_t) * win_target_pool_size,
                        mpi_errno, "RMA target pool");
    (*win_ptr)->target_pool = NULL;
    (*win_ptr)->target_pool_tail = NULL;
    for (i = 0; i < win_target_pool_size; i++) {
        (*win_ptr)->target_pool_start[i].pool_type = MPIDI_RMA_POOL_WIN;
        MPL_LL_APPEND((*win_ptr)->target_pool, (*win_ptr)->target_pool_tail, &((*win_ptr)->target_pool_start[i]));
    }

Xin Zhao's avatar
Xin Zhao committed
371 372 373 374 375 376 377 378
    (*win_ptr)->num_slots = MPIR_MIN(MPIR_CVAR_CH3_RMA_SLOTS_SIZE, MPIR_Comm_size(win_comm_ptr));
    MPIU_CHKPMEM_MALLOC((*win_ptr)->slots, struct MPIDI_RMA_Slot *,
                        sizeof(MPIDI_RMA_Slot_t) * (*win_ptr)->num_slots, mpi_errno, "RMA slots");
    for (i = 0; i < (*win_ptr)->num_slots; i++) {
        (*win_ptr)->slots[i].target_list = NULL;
        (*win_ptr)->slots[i].target_list_tail = NULL;
    }

379 380
    MPID_WIN_FTABLE_SET_DEFAULTS(win_ptr);

381
  fn_exit:
382 383
    MPIDI_FUNC_EXIT(MPID_STATE_WIN_INIT);
    return mpi_errno;
384
  fn_fail:
385
    MPIU_CHKPMEM_REAP();
386 387
    goto fn_exit;
}
388 389 390 391 392 393


#undef FUNCNAME
#define FUNCNAME MPID_Win_set_info
#undef FCNAME
#define FCNAME MPIDI_QUOTE(FUNCNAME)
394
int MPID_Win_set_info(MPID_Win * win, MPID_Info * info)
395 396 397 398 399 400 401
{
    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);
402 403 404
    if (mpi_errno != MPI_SUCCESS) {
        MPIU_ERR_POP(mpi_errno);
    }
405

406
  fn_exit:
407 408
    MPIDI_FUNC_EXIT(MPID_STATE_MPID_WIN_SET_INFO);
    return mpi_errno;
409
  fn_fail:
410 411 412 413 414 415 416 417
    goto fn_exit;
}


#undef FUNCNAME
#define FUNCNAME MPID_Win_get_info
#undef FCNAME
#define FCNAME MPIDI_QUOTE(FUNCNAME)
418
int MPID_Win_get_info(MPID_Win * win, MPID_Info ** info_used)
419 420 421 422 423 424 425
{
    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);
426 427 428
    if (mpi_errno != MPI_SUCCESS) {
        MPIU_ERR_POP(mpi_errno);
    }
429

430
  fn_exit:
431 432
    MPIDI_FUNC_EXIT(MPID_STATE_MPID_WIN_GET_INFO);
    return mpi_errno;
433
  fn_fail:
434 435
    goto fn_exit;
}