static void _shmem_broadcast(void *target, const void *source, size_t nbytes, int PE_root, int PE_start, int logPE_stride, int PE_size, long *pSync) { int rc = OSHMEM_SUCCESS; oshmem_group_t* group = NULL; if ((0 <= PE_root) && (PE_root < PE_size)) { /* Create group basing PE_start, logPE_stride and PE_size */ #if OSHMEM_GROUP_CACHE_ENABLED == 0 group = oshmem_proc_group_create(PE_start, (1 << logPE_stride), PE_size); if (!group || (PE_root >= group->proc_count)) { rc = OSHMEM_ERROR; } #else group = find_group_in_cache(PE_start, logPE_stride, PE_size); if (!group) { group = oshmem_proc_group_create(PE_start, (1 << logPE_stride), PE_size); if (!group || (PE_root >= group->proc_count)) { rc = OSHMEM_ERROR; } else { cache_group(group, PE_start, logPE_stride, PE_size); } } #endif /* OSHMEM_GROUP_CACHE_ENABLED */ /* Collective operation call */ if (rc == OSHMEM_SUCCESS) { /* Define actual PE using relative in active set */ PE_root = oshmem_proc_pe(group->proc_array[PE_root]); /* Call collective broadcast operation */ rc = group->g_scoll.scoll_broadcast(group, PE_root, target, source, nbytes, pSync, SCOLL_DEFAULT_ALG); } #if OSHMEM_GROUP_CACHE_ENABLED == 0 if ( rc == OSHMEM_SUCCESS ) { oshmem_proc_group_destroy(group); } #endif /* OSHMEM_GROUP_CACHE_ENABLED */ } }
int oshmem_group_cache_list_free(void) { oshmem_group_cache_t *cached_group = NULL; opal_list_item_t *item; while (NULL != (item = opal_list_remove_first(&oshmem_group_cache_list))) { cached_group = (oshmem_group_cache_t *) item; oshmem_proc_group_destroy(cached_group->group); OBJ_RELEASE(cached_group); } return OSHMEM_SUCCESS; }
static void _shmem_alltoall(void *target, const void *source, ptrdiff_t dst, ptrdiff_t sst, size_t nelems, size_t element_size, int PE_start, int logPE_stride, int PE_size, long *pSync) { int rc = OSHMEM_SUCCESS; oshmem_group_t* group = NULL; if ((0 <= PE_start) && (0 <= logPE_stride)) { /* Create group basing PE_start, logPE_stride and PE_size */ #if OSHMEM_GROUP_CACHE_ENABLED == 0 group = oshmem_proc_group_create(PE_start, (1 << logPE_stride), PE_size); if (!group) rc = OSHMEM_ERROR; #else group = find_group_in_cache(PE_start, logPE_stride, PE_size); if (!group) { group = oshmem_proc_group_create(PE_start, (1 << logPE_stride), PE_size); if (!group) { rc = OSHMEM_ERROR; } else { cache_group(group, PE_start, logPE_stride, PE_size); } } #endif /* OSHMEM_GROUP_CACHE_ENABLED */ /* Collective operation call */ if (rc == OSHMEM_SUCCESS) { /* Call collective alltoall operation */ rc = group->g_scoll.scoll_alltoall(group, target, source, dst, sst, nelems, element_size, pSync, SCOLL_DEFAULT_ALG); } #if OSHMEM_GROUP_CACHE_ENABLED == 0 if ( rc == OSHMEM_SUCCESS ) { oshmem_proc_group_destroy(group); } #endif /* OSHMEM_GROUP_CACHE_ENABLED */ } }
OSHMEM_DECLSPEC int oshmem_proc_group_init(void) { /* Setup communicator array */ OBJ_CONSTRUCT(&oshmem_group_array, opal_pointer_array_t); if (OPAL_SUCCESS != opal_pointer_array_init(&oshmem_group_array, 0, ORTE_GLOBAL_ARRAY_MAX_SIZE, 1)) { return OSHMEM_ERROR; } /* Setup SHMEM_GROUP_ALL */ if (NULL == (oshmem_group_all = oshmem_proc_group_create(0, 1, opal_list_get_size(&oshmem_proc_list)))) { oshmem_proc_group_destroy(oshmem_group_all); return OSHMEM_ERROR; } /* Setup SHMEM_GROUP_SELF */ if (NULL == (oshmem_group_self = oshmem_proc_group_create(oshmem_proc_local() ->proc_name .vpid, 0, 1))) { oshmem_proc_group_destroy(oshmem_group_self); return OSHMEM_ERROR; } /* Setup SHMEM_GROUP_NULL */ oshmem_group_null = NULL; return OSHMEM_SUCCESS; }
static void __shmem_collect(void *target, const void *source, size_t nbytes, int PE_start, int logPE_stride, int PE_size, long *pSync, bool array_type) { int rc = OSHMEM_SUCCESS; oshmem_group_t* group = NULL; { /* Create group basing PE_start, logPE_stride and PE_size */ #if OSHMEM_GROUP_CACHE_ENABLED == 0 group = oshmem_proc_group_create(PE_start, (1 << logPE_stride), PE_size); if (!group) rc = OSHMEM_ERROR; #else group = find_group_in_cache(PE_start, logPE_stride, PE_size); if (!group) { group = oshmem_proc_group_create(PE_start, (1 << logPE_stride), PE_size); if (!group) { rc = OSHMEM_ERROR; } else { cache_group(group, PE_start, logPE_stride, PE_size); } } #endif /* OSHMEM_GROUP_CACHE_ENABLED */ /* Collective operation call */ if (rc == OSHMEM_SUCCESS) { /* Call collective broadcast operation */ rc = group->g_scoll.scoll_collect(group, target, source, nbytes, pSync, array_type, SCOLL_DEFAULT_ALG); } #if OSHMEM_GROUP_CACHE_ENABLED == 0 if ( rc == OSHMEM_SUCCESS ) { oshmem_proc_group_destroy(group); } #endif /* OSHMEM_GROUP_CACHE_ENABLED */ } }
void shmem_barrier(int PE_start, int logPE_stride, int PE_size, long *pSync) { int rc = OSHMEM_SUCCESS; oshmem_group_t* group = NULL; RUNTIME_CHECK_INIT(); #if OSHMEM_SPEC_COMPAT == 1 /* all outstanding puts must be completed */ shmem_fence(); #endif if ((0 <= PE_start) && (0 <= logPE_stride)) { /* Create group basing PE_start, logPE_stride and PE_size */ #if OSHMEM_GROUP_CACHE_ENABLED == 0 group = oshmem_proc_group_create(PE_start, (1 << logPE_stride), PE_size); if (!group) rc = OSHMEM_ERROR; #else group = find_group_in_cache(PE_start, logPE_stride, PE_size); if (!group) { group = oshmem_proc_group_create(PE_start, (1 << logPE_stride), PE_size); if (!group) { rc = OSHMEM_ERROR; } else { cache_group(group, PE_start, logPE_stride, PE_size); } } #endif /* OSHMEM_GROUP_CACHE_ENABLED */ /* Collective operation call */ if (rc == OSHMEM_SUCCESS) { /* Call barrier operation */ rc = group->g_scoll.scoll_barrier(group, pSync, SCOLL_DEFAULT_ALG); } #if OSHMEM_GROUP_CACHE_ENABLED == 0 if ( rc == OSHMEM_SUCCESS ) { oshmem_proc_group_destroy(group); } #endif /* OSHMEM_GROUP_CACHE_ENABLED */ } RUNTIME_CHECK_RC(rc); }
OSHMEM_DECLSPEC int oshmem_proc_group_finalize(void) { int max, i; oshmem_group_t *group; /* Check whether we have some left */ max = opal_pointer_array_get_size(&oshmem_group_array); for (i = 0; i < max; i++) { group = (oshmem_group_t *) opal_pointer_array_get_item(&oshmem_group_array, i); if (NULL != group) { /* Group has not been freed before finalize */ oshmem_proc_group_destroy(group); } } OBJ_DESTRUCT(&oshmem_group_array); return OSHMEM_SUCCESS; }
int cache_group(oshmem_group_t *group, int PE_start, int logPE_stride, int PE_size) { oshmem_group_cache_t *cached_group = NULL; cached_group = OBJ_NEW(oshmem_group_cache_t); #if OPAL_ENABLE_DEBUG cached_group->item.opal_list_item_belong_to = NULL; cached_group->item.opal_list_item_refcount = 0; #endif cached_group->group = group; cached_group->cache_id[0] = PE_start; cached_group->cache_id[1] = logPE_stride; cached_group->cache_id[2] = PE_size; if (opal_list_get_size(&oshmem_group_cache_list) < oshmem_group_cache_size) { opal_list_append(&oshmem_group_cache_list, (opal_list_item_t *)cached_group); } else { #if ABORT_ON_CACHE_OVERFLOW opal_output(0, "error: group cache overflow on rank %i: cache_size = %u: try encreasing oshmem_group_cache_size mca parameter", group->my_pe, oshmem_group_cache_size); oshmem_shmem_abort(-1); #else /*This part of code makes FIFO group cache management. Define ABORT_ON_CACHE_OVERFLOW as 0 to enable this.*/ oshmem_group_cache_t *cached_group_to_remove = (oshmem_group_cache_t *)opal_list_remove_first(&oshmem_group_cache_list); oshmem_proc_group_destroy(cached_group_to_remove->group); OBJ_RELEASE(cached_group_to_remove); opal_list_append(&oshmem_group_cache_list,(opal_list_item_t *)cached_group); #endif } return OSHMEM_SUCCESS; }
OSHMEM_DECLSPEC oshmem_group_t* oshmem_proc_group_create(int pe_start, int pe_stride, size_t pe_size) { int cur_pe, count_pe; int i; oshmem_group_t* group = NULL; oshmem_proc_t** proc_array = NULL; oshmem_proc_t* proc = NULL; group = OBJ_NEW(oshmem_group_t); if (group) { cur_pe = 0; count_pe = 0; OPAL_THREAD_LOCK(&oshmem_proc_lock); /* allocate an array */ proc_array = (oshmem_proc_t**) malloc(pe_size * sizeof(oshmem_proc_t*)); if (NULL == proc_array) { OPAL_THREAD_UNLOCK(&oshmem_proc_lock); return NULL ; } group->my_pe = OSHMEM_PROC_VPID(oshmem_proc_local()); group->is_member = 0; /* now save only the procs that match this jobid */ for (proc = (oshmem_proc_t*) opal_list_get_first(&oshmem_proc_list); proc != (oshmem_proc_t*) opal_list_get_end(&oshmem_proc_list); proc = (oshmem_proc_t*) opal_list_get_next(proc)) { if (count_pe >= (int) pe_size) { break; } else if ((cur_pe >= pe_start) && ((pe_stride == 0) || (((cur_pe - pe_start) % pe_stride) == 0))) { proc_array[count_pe++] = proc; if (oshmem_proc_pe(proc) == group->my_pe) group->is_member = 1; } cur_pe++; } group->proc_array = proc_array; group->proc_count = (int) count_pe; group->ompi_comm = NULL; /* Prepare peers list */ OBJ_CONSTRUCT(&(group->peer_list), opal_list_t); { orte_namelist_t *peer = NULL; for (i = 0; i < group->proc_count; i++) { peer = OBJ_NEW(orte_namelist_t); peer->name.jobid = OSHMEM_PROC_JOBID(group->proc_array[i]); peer->name.vpid = OSHMEM_PROC_VPID(group->proc_array[i]); opal_list_append(&(group->peer_list), &peer->super); } } group->id = opal_pointer_array_add(&oshmem_group_array, group); memset(&group->g_scoll, 0, sizeof(mca_scoll_base_group_scoll_t)); if (OSHMEM_SUCCESS != mca_scoll_base_select(group)) { opal_output(0, "Error: No collective modules are available: group is not created, returning NULL"); oshmem_proc_group_destroy(group); OPAL_THREAD_UNLOCK(&oshmem_proc_lock); return NULL ; } OPAL_THREAD_UNLOCK(&oshmem_proc_lock); } return group; }