int MPID_Put(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, MPID_Win *win) { int mpi_errno = MPI_SUCCESS; MPIDI_Win_request *req = MPIU_Calloc0(1, MPIDI_Win_request); req->win = win; if(win->mpid.request_based != 1) req->type = MPIDI_WIN_REQUEST_PUT; else { req->req_handle = win->mpid.rreq; req->type = MPIDI_WIN_REQUEST_RPUT; req->req_handle->mpid.win_req = req; } if(win->mpid.sync.origin_epoch_type == win->mpid.sync.target_epoch_type && win->mpid.sync.origin_epoch_type == MPID_EPOTYPE_REFENCE){ win->mpid.sync.origin_epoch_type = MPID_EPOTYPE_FENCE; win->mpid.sync.target_epoch_type = MPID_EPOTYPE_FENCE; } if(win->mpid.sync.origin_epoch_type == MPID_EPOTYPE_NONE || win->mpid.sync.origin_epoch_type == MPID_EPOTYPE_POST){ MPIU_ERR_SETANDSTMT(mpi_errno, MPI_ERR_RMA_SYNC, return mpi_errno, "**rmasync"); }
void MPIDI_Coll_comm_create(MPID_Comm *comm) { volatile int geom_init = 1; int i; MPIDI_Post_geom_create_t geom_post; TRACE_ERR("MPIDI_Coll_comm_create enter\n"); if (!MPIDI_Process.optimized.collectives) return; if(comm->comm_kind != MPID_INTRACOMM) return; /* Create a geometry */ comm->coll_fns = MPIU_Calloc0(1, MPID_Collops); MPID_assert(comm->coll_fns != NULL); if(comm->mpid.geometry != MPIDI_Process.world_geometry) { if(unlikely(MPIDI_Process.verbose >= MPIDI_VERBOSE_DETAILS_0 && comm->rank == 0)) fprintf(stderr,"world geom: %p parent geom: %p\n", MPIDI_Process.world_geometry, comm->mpid.parent); TRACE_ERR("Creating subgeom\n"); /* Change to this at some point */ comm->mpid.tasks = NULL; for(i=1;i<comm->local_size;i++) { /* only if sequential tasks should we use a (single) range. Multi or reordered ranges are inefficient */ if(MPID_VCR_GET_LPID(comm->vcr, i) != (MPID_VCR_GET_LPID(comm->vcr, i-1) + 1)) { /* not sequential, use tasklist */ MPID_VCR_GET_LPIDS(comm, comm->mpid.tasks); break; } } /* Should we use a range? (no task list set) */ if(comm->mpid.tasks == NULL) { /* one range, {first rank ... last rank} */ comm->mpid.range.lo = MPID_VCR_GET_LPID(comm->vcr, 0); comm->mpid.range.hi = MPID_VCR_GET_LPID(comm->vcr, comm->local_size-1); } if(unlikely(MPIDI_Process.verbose >= MPIDI_VERBOSE_DETAILS_0 && comm->rank == 0)) fprintf(stderr,"create geometry tasks %p {%u..%u}\n", comm->mpid.tasks, MPID_VCR_GET_LPID(comm->vcr, 0),MPID_VCR_GET_LPID(comm->vcr, comm->local_size-1)); pami_configuration_t config[3]; size_t numconfigs = 0; #ifdef HAVE_PAMI_GEOMETRY_NONCONTIG config[0].name = PAMI_GEOMETRY_NONCONTIG; if(MPIDI_Process.optimized.memory & MPID_OPT_LVL_NONCONTIG) config[0].value.intval = 0; // Disable non-contig, pamid doesn't use pami for non-contig data collectives else config[0].value.intval = 1; // Enable non-contig even though pamid doesn't use pami for non-contig data collectives, // we still possibly want those collectives for other reasons. ++numconfigs; #endif if(MPIDI_Process.optimized.subcomms) { config[numconfigs].name = PAMI_GEOMETRY_OPTIMIZE; config[numconfigs].value.intval = 1; ++numconfigs; } #ifdef HAVE_PAMI_GEOMETRY_MEMORY_OPTIMIZE if(MPIDI_Process.optimized.memory) { config[numconfigs].name = PAMI_GEOMETRY_MEMORY_OPTIMIZE; config[numconfigs].value.intval = MPIDI_Process.optimized.memory; /* level of optimization */ ++numconfigs; } #endif if((MPIDI_Process.optimized.memory & MPID_OPT_LVL_IRREG) && (comm->local_size & (comm->local_size-1))) { /* Don't create irregular geometries. Fallback to MPICH only collectives */ geom_init = 0; comm->mpid.geometry = PAMI_GEOMETRY_NULL; } else if(comm->mpid.tasks == NULL) { geom_post.client = MPIDI_Client; geom_post.configs = config; geom_post.context_offset = 0; /* TODO BES investigate */ geom_post.num_configs = numconfigs; geom_post.newgeom = &comm->mpid.geometry, geom_post.parent = PAMI_GEOMETRY_NULL; geom_post.id = comm->context_id; geom_post.ranges = &comm->mpid.range; geom_post.tasks = NULL;; geom_post.count = (size_t)1; geom_post.fn = geom_create_cb_done; geom_post.cookie = (void*)&geom_init; TRACE_ERR("%s geom_rangelist_create\n", MPIDI_Process.context_post>0?"Posting":"Invoking"); MPIDI_Context_post(MPIDI_Context[0], &geom_post.state, geom_rangelist_create_wrapper, (void *)&geom_post); } else { geom_post.client = MPIDI_Client; geom_post.configs = config; geom_post.context_offset = 0; /* TODO BES investigate */ geom_post.num_configs = numconfigs; geom_post.newgeom = &comm->mpid.geometry, geom_post.parent = PAMI_GEOMETRY_NULL; geom_post.id = comm->context_id; geom_post.ranges = NULL; geom_post.tasks = comm->mpid.tasks; geom_post.count = (size_t)comm->local_size; geom_post.fn = geom_create_cb_done; geom_post.cookie = (void*)&geom_init; TRACE_ERR("%s geom_tasklist_create\n", MPIDI_Process.context_post>0?"Posting":"Invoking"); MPIDI_Context_post(MPIDI_Context[0], &geom_post.state, geom_tasklist_create_wrapper, (void *)&geom_post); } TRACE_ERR("Waiting for geom create to finish\n"); MPID_PROGRESS_WAIT_WHILE(geom_init); if(comm->mpid.geometry == PAMI_GEOMETRY_NULL) { if(unlikely(MPIDI_Process.verbose >= MPIDI_VERBOSE_DETAILS_0 && comm->rank == 0)) fprintf(stderr,"Created unoptimized communicator id=%u, size=%u\n", (unsigned) comm->context_id,comm->local_size); MPIU_TestFree(&comm->coll_fns); return; } } /* Initialize the async flow control in case it will be used. */ comm->mpid.num_requests = MPIDI_Process.optimized.num_requests; TRACE_ERR("Querying protocols\n"); /* Determine what protocols are available for this comm/geom */ /* These two functions moved to mpid_collselect.c */ MPIDI_Comm_coll_query(comm); MPIDI_Comm_coll_envvars(comm); if(MPIDI_Process.optimized.select_colls) MPIDI_Comm_coll_select(comm); TRACE_ERR("mpir barrier\n"); int mpierrno = FALSE; /* Switch to comm->coll_fns->fn() */ MPIDO_Barrier(comm, &mpierrno); TRACE_ERR("MPIDI_Coll_comm_create exit\n"); }