int MPIR_Group_create( int nproc, MPIR_Group **new_group_ptr ) { int mpi_errno = MPI_SUCCESS; *new_group_ptr = (MPIR_Group *)MPIR_Handle_obj_alloc( &MPIR_Group_mem ); /* --BEGIN ERROR HANDLING-- */ if (!*new_group_ptr) { mpi_errno = MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, "MPIR_Group_create", __LINE__, MPI_ERR_OTHER, "**nomem", 0 ); return mpi_errno; } /* --END ERROR HANDLING-- */ MPIR_Object_set_ref( *new_group_ptr, 1 ); (*new_group_ptr)->lrank_to_lpid = (MPII_Group_pmap_t *)MPL_malloc( nproc * sizeof(MPII_Group_pmap_t) ); /* --BEGIN ERROR HANDLING-- */ if (!(*new_group_ptr)->lrank_to_lpid) { MPIR_Handle_obj_free( &MPIR_Group_mem, *new_group_ptr ); *new_group_ptr = NULL; MPIR_CHKMEM_SETERR(mpi_errno,nproc*sizeof(MPII_Group_pmap_t), "newgroup->lrank_to_lpid"); return mpi_errno; } /* --END ERROR HANDLING-- */ (*new_group_ptr)->size = nproc; /* Make sure that there is no question that the list of ranks sorted by pids is marked as uninitialized */ (*new_group_ptr)->idx_of_first_lpid = -1; (*new_group_ptr)->is_local_dense_monotonic = FALSE; return mpi_errno; }
/* Provides a way to trap all attribute allocations when debugging leaks. */ MPIR_Attribute *MPID_Attr_alloc(void) { MPIR_Attribute *attr = (MPIR_Attribute *) MPIR_Handle_obj_alloc(&MPID_Attr_mem); /* attributes don't have refcount semantics, but let's keep valgrind and * the debug logging pacified */ MPIR_Assert(attr != NULL); MPIR_Object_set_ref(attr, 0); return attr; }
int MPIR_Comm_create_keyval_impl(MPI_Comm_copy_attr_function *comm_copy_attr_fn, MPI_Comm_delete_attr_function *comm_delete_attr_fn, int *comm_keyval, void *extra_state) { int mpi_errno = MPI_SUCCESS; MPII_Keyval *keyval_ptr; keyval_ptr = (MPII_Keyval *)MPIR_Handle_obj_alloc( &MPII_Keyval_mem ); MPIR_ERR_CHKANDJUMP(!keyval_ptr, mpi_errno, MPI_ERR_OTHER,"**nomem"); /* Initialize the attribute dup function */ if (!MPIR_Process.attr_dup) { MPIR_Process.attr_dup = MPIR_Attr_dup_list; MPIR_Process.attr_free = MPIR_Attr_delete_list; } /* The handle encodes the keyval kind. Modify it to have the correct field */ keyval_ptr->handle = (keyval_ptr->handle & ~(0x03c00000)) | (MPIR_COMM << 22); MPIR_Object_set_ref(keyval_ptr,1); keyval_ptr->was_freed = 0; keyval_ptr->kind = MPIR_COMM; keyval_ptr->extra_state = extra_state; keyval_ptr->copyfn.user_function = comm_copy_attr_fn; keyval_ptr->copyfn.proxy = MPII_Attr_copy_c_proxy; keyval_ptr->delfn.user_function = comm_delete_attr_fn; keyval_ptr->delfn.proxy = MPII_Attr_delete_c_proxy; MPIR_OBJ_PUBLISH_HANDLE(*comm_keyval, keyval_ptr->handle); fn_exit: return mpi_errno; fn_fail: goto fn_exit; }
/*@ MPIR_Type_dup - create a copy of a datatype Input Parameters: - oldtype - handle of original datatype Output Parameters: . newtype - handle of newly created copy of datatype Return Value: 0 on success, MPI error code on failure. @*/ int MPIR_Type_dup(MPI_Datatype oldtype, MPI_Datatype * newtype) { int mpi_errno = MPI_SUCCESS; MPIR_Datatype *new_dtp = 0, *old_dtp; if (HANDLE_GET_KIND(oldtype) == HANDLE_KIND_BUILTIN) { /* create a new type and commit it. */ mpi_errno = MPIR_Type_contiguous(1, oldtype, newtype); if (mpi_errno) { MPIR_ERR_POP(mpi_errno); } } else { /* allocate new datatype object and handle */ new_dtp = (MPIR_Datatype *) MPIR_Handle_obj_alloc(&MPIR_Datatype_mem); if (!new_dtp) { /* --BEGIN ERROR HANDLING-- */ mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, "MPIR_Type_dup", __LINE__, MPI_ERR_OTHER, "**nomem", 0); goto fn_fail; /* --END ERROR HANDLING-- */ } MPIR_Datatype_get_ptr(oldtype, old_dtp); /* fill in datatype */ MPIR_Object_set_ref(new_dtp, 1); /* new_dtp->handle is filled in by MPIR_Handle_obj_alloc() */ new_dtp->is_contig = old_dtp->is_contig; new_dtp->size = old_dtp->size; new_dtp->extent = old_dtp->extent; new_dtp->ub = old_dtp->ub; new_dtp->lb = old_dtp->lb; new_dtp->true_ub = old_dtp->true_ub; new_dtp->true_lb = old_dtp->true_lb; new_dtp->alignsize = old_dtp->alignsize; new_dtp->has_sticky_ub = old_dtp->has_sticky_ub; new_dtp->has_sticky_lb = old_dtp->has_sticky_lb; new_dtp->is_committed = old_dtp->is_committed; new_dtp->attributes = NULL; /* Attributes are copied in the * top-level MPI_Type_dup routine */ new_dtp->name[0] = 0; /* The Object name is not copied on * a dup */ new_dtp->n_builtin_elements = old_dtp->n_builtin_elements; new_dtp->builtin_element_size = old_dtp->builtin_element_size; new_dtp->basic_type = old_dtp->basic_type; new_dtp->max_contig_blocks = old_dtp->max_contig_blocks; new_dtp->dataloop = NULL; new_dtp->dataloop_size = old_dtp->dataloop_size; *newtype = new_dtp->handle; if (old_dtp->is_committed) { MPIR_Assert(old_dtp->dataloop != NULL); MPIR_Dataloop_dup(old_dtp->dataloop, old_dtp->dataloop_size, &new_dtp->dataloop); MPID_Type_commit_hook(new_dtp); } } MPL_DBG_MSG_D(MPIR_DBG_DATATYPE, VERBOSE, "dup type %x created.", *newtype); fn_fail: return mpi_errno; }
/*@ MPIDU_Type_vector - create a vector datatype Input Parameters: + count - number of blocks in vector . blocklength - number of elements in each block . stride - distance from beginning of one block to the next (see next parameter for units) . strideinbytes - if nonzero, then stride is in bytes, otherwise stride is in terms of extent of oldtype - oldtype - type (using handle) of datatype on which vector is based Output Parameters: . newtype - handle of new vector datatype Return Value: 0 on success, MPI error code on failure. @*/ int MPIDU_Type_vector(int count, int blocklength, MPI_Aint stride, int strideinbytes, MPI_Datatype oldtype, MPI_Datatype *newtype) { int mpi_errno = MPI_SUCCESS; int is_builtin, old_is_contig; MPI_Aint el_sz, old_sz; MPI_Datatype el_type; MPI_Aint old_lb, old_ub, old_extent, old_true_lb, old_true_ub, eff_stride; MPIDU_Datatype *new_dtp; if (count == 0) return MPIDU_Type_zerolen(newtype); /* allocate new datatype object and handle */ new_dtp = (MPIDU_Datatype *) MPIR_Handle_obj_alloc(&MPIDU_Datatype_mem); if (!new_dtp) { /* --BEGIN ERROR HANDLING-- */ mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, "MPIDU_Type_vector", __LINE__, MPI_ERR_OTHER, "**nomem", 0); return mpi_errno; /* --END ERROR HANDLING-- */ } /* handle is filled in by MPIR_Handle_obj_alloc() */ MPIR_Object_set_ref(new_dtp, 1); new_dtp->is_permanent = 0; new_dtp->is_committed = 0; new_dtp->attributes = NULL; new_dtp->cache_id = 0; new_dtp->name[0] = 0; new_dtp->contents = NULL; new_dtp->dataloop = NULL; new_dtp->dataloop_size = -1; new_dtp->dataloop_depth = -1; new_dtp->hetero_dloop = NULL; new_dtp->hetero_dloop_size = -1; new_dtp->hetero_dloop_depth = -1; is_builtin = (HANDLE_GET_KIND(oldtype) == HANDLE_KIND_BUILTIN); if (is_builtin) { el_sz = (MPI_Aint) MPIDU_Datatype_get_basic_size(oldtype); el_type = oldtype; old_lb = 0; old_true_lb = 0; old_ub = el_sz; old_true_ub = el_sz; old_sz = el_sz; old_extent = el_sz; old_is_contig = 1; new_dtp->size = (MPI_Aint) count * (MPI_Aint) blocklength * el_sz; new_dtp->has_sticky_lb = 0; new_dtp->has_sticky_ub = 0; new_dtp->alignsize = el_sz; /* ??? */ new_dtp->n_builtin_elements = count * blocklength; new_dtp->builtin_element_size = el_sz; new_dtp->basic_type = el_type; new_dtp->max_contig_blocks = count; eff_stride = (strideinbytes) ? stride : (stride * el_sz); } else /* user-defined base type (oldtype) */ { MPIDU_Datatype *old_dtp; MPIDU_Datatype_get_ptr(oldtype, old_dtp); el_sz = old_dtp->builtin_element_size; el_type = old_dtp->basic_type; old_lb = old_dtp->lb; old_true_lb = old_dtp->true_lb; old_ub = old_dtp->ub; old_true_ub = old_dtp->true_ub; old_sz = old_dtp->size; old_extent = old_dtp->extent; old_is_contig = old_dtp->is_contig; new_dtp->size = count * blocklength * old_dtp->size; new_dtp->has_sticky_lb = old_dtp->has_sticky_lb; new_dtp->has_sticky_ub = old_dtp->has_sticky_ub; new_dtp->alignsize = old_dtp->alignsize; new_dtp->n_builtin_elements = count * blocklength * old_dtp->n_builtin_elements; new_dtp->builtin_element_size = el_sz; new_dtp->basic_type = el_type; new_dtp->max_contig_blocks = old_dtp->max_contig_blocks * count * blocklength; eff_stride = (strideinbytes) ? stride : (stride * old_dtp->extent); } MPIDU_DATATYPE_VECTOR_LB_UB((MPI_Aint) count, eff_stride, (MPI_Aint) blocklength, old_lb, old_ub, old_extent, new_dtp->lb, new_dtp->ub); new_dtp->true_lb = new_dtp->lb + (old_true_lb - old_lb); new_dtp->true_ub = new_dtp->ub + (old_true_ub - old_ub); new_dtp->extent = new_dtp->ub - new_dtp->lb; /* new type is only contig for N types if old one was, and * size and extent of new type are equivalent, and stride is * equal to blocklength * size of old type. */ if ((MPI_Aint)(new_dtp->size) == new_dtp->extent && eff_stride == (MPI_Aint) blocklength * old_sz && old_is_contig) { new_dtp->is_contig = 1; new_dtp->max_contig_blocks = 1; } else { new_dtp->is_contig = 0; } *newtype = new_dtp->handle; MPL_DBG_MSG_P(MPIR_DBG_DATATYPE,VERBOSE,"vector type %x created.", new_dtp->handle); return mpi_errno; }
static int win_init(MPI_Aint size, int disp_unit, int create_flavor, int model, MPIR_Info * info, MPIR_Comm * comm_ptr, MPIR_Win ** win_ptr) { int mpi_errno = MPI_SUCCESS; int i; MPIR_Comm *win_comm_ptr; int win_target_pool_size; MPIR_CHKPMEM_DECL(5); MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_WIN_INIT); MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_WIN_INIT); MPID_THREAD_CS_ENTER(POBJ, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX); if (initRMAoptions) { MPIDI_CH3_RMA_Init_sync_pvars(); MPIDI_CH3_RMA_Init_pkthandler_pvars(); initRMAoptions = 0; } MPID_THREAD_CS_EXIT(POBJ, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX); *win_ptr = (MPIR_Win *) MPIR_Handle_obj_alloc(&MPIR_Win_mem); MPIR_ERR_CHKANDJUMP1(!(*win_ptr), mpi_errno, MPI_ERR_OTHER, "**nomem", "**nomem %s", "MPIR_Win_mem"); mpi_errno = MPIR_Comm_dup_impl(comm_ptr, &win_comm_ptr); if (mpi_errno) MPIR_ERR_POP(mpi_errno); MPIR_Object_set_ref(*win_ptr, 1); /* (*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)->comm_ptr = win_comm_ptr; (*win_ptr)->at_completion_counter = 0; (*win_ptr)->shm_base_addrs = NULL; /* (*win_ptr)->basic_info_table[] is set by caller; */ (*win_ptr)->current_lock_type = MPID_LOCK_NONE; (*win_ptr)->shared_lock_ref_cnt = 0; (*win_ptr)->target_lock_queue_head = NULL; (*win_ptr)->shm_allocated = FALSE; (*win_ptr)->states.access_state = MPIDI_RMA_NONE; (*win_ptr)->states.exposure_state = MPIDI_RMA_NONE; (*win_ptr)->num_targets_with_pending_net_ops = 0; (*win_ptr)->start_ranks_in_win_grp = NULL; (*win_ptr)->start_grp_size = 0; (*win_ptr)->lock_all_assert = 0; (*win_ptr)->lock_epoch_count = 0; (*win_ptr)->outstanding_locks = 0; (*win_ptr)->current_target_lock_data_bytes = 0; (*win_ptr)->sync_request_cnt = 0; (*win_ptr)->active = FALSE; (*win_ptr)->next = NULL; (*win_ptr)->prev = NULL; (*win_ptr)->outstanding_acks = 0; /* 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.same_disp_unit = FALSE; (*win_ptr)->info_args.alloc_shared_noncontig = 0; (*win_ptr)->info_args.alloc_shm = FALSE; if ((*win_ptr)->create_flavor == MPI_WIN_FLAVOR_ALLOCATE || (*win_ptr)->create_flavor == MPI_WIN_FLAVOR_SHARED) { (*win_ptr)->info_args.alloc_shm = TRUE; } /* Set info_args on window based on info provided by user */ mpi_errno = MPID_Win_set_info((*win_ptr), info); if (mpi_errno != MPI_SUCCESS) MPIR_ERR_POP(mpi_errno); MPIR_CHKPMEM_MALLOC((*win_ptr)->op_pool_start, MPIDI_RMA_Op_t *, sizeof(MPIDI_RMA_Op_t) * MPIR_CVAR_CH3_RMA_OP_WIN_POOL_SIZE, mpi_errno, "RMA op pool", MPL_MEM_RMA); (*win_ptr)->op_pool_head = 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; DL_APPEND((*win_ptr)->op_pool_head, &((*win_ptr)->op_pool_start[i])); } win_target_pool_size = MPL_MIN(MPIR_CVAR_CH3_RMA_TARGET_WIN_POOL_SIZE, MPIR_Comm_size(win_comm_ptr)); MPIR_CHKPMEM_MALLOC((*win_ptr)->target_pool_start, MPIDI_RMA_Target_t *, sizeof(MPIDI_RMA_Target_t) * win_target_pool_size, mpi_errno, "RMA target pool", MPL_MEM_RMA); (*win_ptr)->target_pool_head = NULL; for (i = 0; i < win_target_pool_size; i++) { (*win_ptr)->target_pool_start[i].pool_type = MPIDI_RMA_POOL_WIN; DL_APPEND((*win_ptr)->target_pool_head, &((*win_ptr)->target_pool_start[i])); } (*win_ptr)->num_slots = MPL_MIN(MPIR_CVAR_CH3_RMA_SLOTS_SIZE, MPIR_Comm_size(win_comm_ptr)); MPIR_CHKPMEM_MALLOC((*win_ptr)->slots, MPIDI_RMA_Slot_t *, sizeof(MPIDI_RMA_Slot_t) * (*win_ptr)->num_slots, mpi_errno, "RMA slots", MPL_MEM_RMA); for (i = 0; i < (*win_ptr)->num_slots; i++) { (*win_ptr)->slots[i].target_list_head = NULL; } MPIR_CHKPMEM_MALLOC((*win_ptr)->target_lock_entry_pool_start, MPIDI_RMA_Target_lock_entry_t *, sizeof(MPIDI_RMA_Target_lock_entry_t) * MPIR_CVAR_CH3_RMA_TARGET_LOCK_ENTRY_WIN_POOL_SIZE, mpi_errno, "RMA lock entry pool", MPL_MEM_RMA); (*win_ptr)->target_lock_entry_pool_head = NULL; for (i = 0; i < MPIR_CVAR_CH3_RMA_TARGET_LOCK_ENTRY_WIN_POOL_SIZE; i++) { DL_APPEND((*win_ptr)->target_lock_entry_pool_head, &((*win_ptr)->target_lock_entry_pool_start[i])); } if (MPIDI_RMA_Win_inactive_list_head == NULL && MPIDI_RMA_Win_active_list_head == NULL) { /* this is the first window, register RMA progress hook */ mpi_errno = MPID_Progress_register_hook(MPIDI_CH3I_RMA_Make_progress_global, &MPIDI_CH3I_RMA_Progress_hook_id); if (mpi_errno) { MPIR_ERR_POP(mpi_errno); } } DL_APPEND(MPIDI_RMA_Win_inactive_list_head, (*win_ptr)); if (MPIDI_CH3U_Win_hooks.win_init != NULL) { mpi_errno = MPIDI_CH3U_Win_hooks.win_init(size, disp_unit, create_flavor, model, info, comm_ptr, win_ptr); if (mpi_errno != MPI_SUCCESS) MPIR_ERR_POP(mpi_errno); } fn_exit: MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_WIN_INIT); return mpi_errno; fn_fail: MPIR_CHKPMEM_REAP(); goto fn_exit; }
int MPIDU_Type_indexed(int count, const int *blocklength_array, const void *displacement_array, int dispinbytes, MPI_Datatype oldtype, MPI_Datatype *newtype) { int mpi_errno = MPI_SUCCESS; int is_builtin, old_is_contig; int i; MPI_Aint contig_count; MPI_Aint el_sz, el_ct, old_ct, old_sz; MPI_Aint old_lb, old_ub, old_extent, old_true_lb, old_true_ub; MPI_Aint min_lb = 0, max_ub = 0, eff_disp; MPI_Datatype el_type; MPIDU_Datatype *new_dtp; if (count == 0) return MPIDU_Type_zerolen(newtype); /* sanity check that blocklens are all non-negative */ for (i = 0; i < count; ++i) { DLOOP_Assert(blocklength_array[i] >= 0); } /* allocate new datatype object and handle */ new_dtp = (MPIDU_Datatype *) MPIR_Handle_obj_alloc(&MPIDU_Datatype_mem); /* --BEGIN ERROR HANDLING-- */ if (!new_dtp) { mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, "MPIDU_Type_indexed", __LINE__, MPI_ERR_OTHER, "**nomem", 0); return mpi_errno; } /* --END ERROR HANDLING-- */ /* handle is filled in by MPIR_Handle_obj_alloc() */ MPIR_Object_set_ref(new_dtp, 1); new_dtp->is_permanent = 0; new_dtp->is_committed = 0; new_dtp->attributes = NULL; new_dtp->cache_id = 0; new_dtp->name[0] = 0; new_dtp->contents = NULL; new_dtp->dataloop = NULL; new_dtp->dataloop_size = -1; new_dtp->dataloop_depth = -1; new_dtp->hetero_dloop = NULL; new_dtp->hetero_dloop_size = -1; new_dtp->hetero_dloop_depth = -1; is_builtin = (HANDLE_GET_KIND(oldtype) == HANDLE_KIND_BUILTIN); if (is_builtin) { /* builtins are handled differently than user-defined types because * they have no associated dataloop or datatype structure. */ el_sz = MPIDU_Datatype_get_basic_size(oldtype); old_sz = el_sz; el_ct = 1; el_type = oldtype; old_lb = 0; old_true_lb = 0; old_ub = (MPI_Aint) el_sz; old_true_ub = (MPI_Aint) el_sz; old_extent = (MPI_Aint) el_sz; old_is_contig = 1; new_dtp->has_sticky_ub = 0; new_dtp->has_sticky_lb = 0; MPIR_Assign_trunc(new_dtp->alignsize, el_sz, MPI_Aint); new_dtp->builtin_element_size = el_sz; new_dtp->basic_type = el_type; new_dtp->max_contig_blocks = count; } else { /* user-defined base type (oldtype) */ MPIDU_Datatype *old_dtp; MPIDU_Datatype_get_ptr(oldtype, old_dtp); /* Ensure that "builtin_element_size" fits into an int datatype. */ MPIR_Ensure_Aint_fits_in_int(old_dtp->builtin_element_size); el_sz = old_dtp->builtin_element_size; old_sz = old_dtp->size; el_ct = old_dtp->n_builtin_elements; el_type = old_dtp->basic_type; old_lb = old_dtp->lb; old_true_lb = old_dtp->true_lb; old_ub = old_dtp->ub; old_true_ub = old_dtp->true_ub; old_extent = old_dtp->extent; old_is_contig = old_dtp->is_contig; new_dtp->has_sticky_lb = old_dtp->has_sticky_lb; new_dtp->has_sticky_ub = old_dtp->has_sticky_ub; new_dtp->builtin_element_size = (MPI_Aint) el_sz; new_dtp->basic_type = el_type; new_dtp->max_contig_blocks = 0; for(i=0; i<count; i++) new_dtp->max_contig_blocks += old_dtp->max_contig_blocks * ((MPI_Aint ) blocklength_array[i]); } /* find the first nonzero blocklength element */ i = 0; while (i < count && blocklength_array[i] == 0) i++; if (i == count) { MPIR_Handle_obj_free(&MPIDU_Datatype_mem, new_dtp); return MPIDU_Type_zerolen(newtype); } /* priming for loop */ old_ct = blocklength_array[i]; eff_disp = (dispinbytes) ? ((MPI_Aint *) displacement_array)[i] : (((MPI_Aint) ((int *) displacement_array)[i]) * old_extent); MPIDU_DATATYPE_BLOCK_LB_UB((MPI_Aint) blocklength_array[i], eff_disp, old_lb, old_ub, old_extent, min_lb, max_ub); /* determine min lb, max ub, and count of old types in remaining * nonzero size blocks */ for (i++; i < count; i++) { MPI_Aint tmp_lb, tmp_ub; if (blocklength_array[i] > 0) { old_ct += blocklength_array[i]; /* add more oldtypes */ eff_disp = (dispinbytes) ? ((MPI_Aint *) displacement_array)[i] : (((MPI_Aint) ((int *) displacement_array)[i]) * old_extent); /* calculate ub and lb for this block */ MPIDU_DATATYPE_BLOCK_LB_UB((MPI_Aint)(blocklength_array[i]), eff_disp, old_lb, old_ub, old_extent, tmp_lb, tmp_ub); if (tmp_lb < min_lb) min_lb = tmp_lb; if (tmp_ub > max_ub) max_ub = tmp_ub; } } new_dtp->size = old_ct * old_sz; new_dtp->lb = min_lb; new_dtp->ub = max_ub; new_dtp->true_lb = min_lb + (old_true_lb - old_lb); new_dtp->true_ub = max_ub + (old_true_ub - old_ub); new_dtp->extent = max_ub - min_lb; new_dtp->n_builtin_elements = old_ct * el_ct; /* new type is only contig for N types if it's all one big * block, its size and extent are the same, and the old type * was also contiguous. */ new_dtp->is_contig = 0; if(old_is_contig) { MPI_Aint *blklens = MPL_malloc(count *sizeof(MPI_Aint)); for (i=0; i<count; i++) blklens[i] = blocklength_array[i]; contig_count = MPIDU_Type_indexed_count_contig(count, blklens, displacement_array, dispinbytes, old_extent); new_dtp->max_contig_blocks = contig_count; if( (contig_count == 1) && ((MPI_Aint) new_dtp->size == new_dtp->extent)) { new_dtp->is_contig = 1; } MPL_free(blklens); } *newtype = new_dtp->handle; return mpi_errno; }
/*@ MPIR_Type_contiguous - create a contiguous datatype Input Parameters: + count - number of elements in the contiguous block - oldtype - type (using handle) of datatype on which vector is based Output Parameters: . newtype - handle of new contiguous datatype Return Value: MPI_SUCCESS on success, MPI error code on failure. @*/ int MPIR_Type_contiguous(int count, MPI_Datatype oldtype, MPI_Datatype *newtype) { int mpi_errno = MPI_SUCCESS; int is_builtin; MPI_Aint el_sz; MPI_Datatype el_type; MPIR_Datatype *new_dtp; if (count == 0) return MPII_Type_zerolen(newtype); /* allocate new datatype object and handle */ new_dtp = (MPIR_Datatype *) MPIR_Handle_obj_alloc(&MPIR_Datatype_mem); /* --BEGIN ERROR HANDLING-- */ if (!new_dtp) { mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, "MPIR_Type_contiguous", __LINE__, MPI_ERR_OTHER, "**nomem", 0); return mpi_errno; } /* --END ERROR HANDLING-- */ /* handle is filled in by MPIR_Handle_obj_alloc() */ MPIR_Object_set_ref(new_dtp, 1); new_dtp->is_permanent = 0; new_dtp->is_committed = 0; new_dtp->attributes = NULL; new_dtp->cache_id = 0; new_dtp->name[0] = 0; new_dtp->contents = NULL; new_dtp->dataloop = NULL; new_dtp->dataloop_size = -1; new_dtp->dataloop_depth = -1; new_dtp->hetero_dloop = NULL; new_dtp->hetero_dloop_size = -1; new_dtp->hetero_dloop_depth = -1; is_builtin = (HANDLE_GET_KIND(oldtype) == HANDLE_KIND_BUILTIN); if (is_builtin) { el_sz = MPIR_Datatype_get_basic_size(oldtype); el_type = oldtype; new_dtp->size = count * el_sz; new_dtp->has_sticky_ub = 0; new_dtp->has_sticky_lb = 0; new_dtp->true_lb = 0; new_dtp->lb = 0; new_dtp->true_ub = count * el_sz; new_dtp->ub = new_dtp->true_ub; new_dtp->extent = new_dtp->ub - new_dtp->lb; new_dtp->alignsize = el_sz; new_dtp->n_builtin_elements = count; new_dtp->builtin_element_size = el_sz; new_dtp->basic_type = el_type; new_dtp->is_contig = 1; new_dtp->max_contig_blocks = 1; } else { /* user-defined base type (oldtype) */ MPIR_Datatype *old_dtp; MPIR_Datatype_get_ptr(oldtype, old_dtp); el_sz = old_dtp->builtin_element_size; el_type = old_dtp->basic_type; new_dtp->size = count * old_dtp->size; new_dtp->has_sticky_ub = old_dtp->has_sticky_ub; new_dtp->has_sticky_lb = old_dtp->has_sticky_lb; MPII_DATATYPE_CONTIG_LB_UB((MPI_Aint) count, old_dtp->lb, old_dtp->ub, old_dtp->extent, new_dtp->lb, new_dtp->ub); /* easiest to calc true lb/ub relative to lb/ub; doesn't matter * if there are sticky lb/ubs or not when doing this. */ new_dtp->true_lb = new_dtp->lb + (old_dtp->true_lb - old_dtp->lb); new_dtp->true_ub = new_dtp->ub + (old_dtp->true_ub - old_dtp->ub); new_dtp->extent = new_dtp->ub - new_dtp->lb; new_dtp->alignsize = old_dtp->alignsize; new_dtp->n_builtin_elements = count * old_dtp->n_builtin_elements; new_dtp->builtin_element_size = old_dtp->builtin_element_size; new_dtp->basic_type = el_type; MPIR_Datatype_is_contig(oldtype, &new_dtp->is_contig); if(new_dtp->is_contig) new_dtp->max_contig_blocks = 1; else new_dtp->max_contig_blocks = count * old_dtp->max_contig_blocks; } *newtype = new_dtp->handle; MPL_DBG_MSG_P(MPIR_DBG_DATATYPE,VERBOSE,"contig type %x created.", new_dtp->handle); return mpi_errno; }
/*@ MPIR_Type_blockindexed - create a block indexed datatype Input Parameters: + count - number of blocks in type . blocklength - number of elements in each block . displacement_array - offsets of blocks from start of type (see next parameter for units) . dispinbytes - if nonzero, then displacements are in bytes, otherwise they in terms of extent of oldtype - oldtype - type (using handle) of datatype on which new type is based Output Parameters: . newtype - handle of new block indexed datatype Return Value: MPI_SUCCESS on success, MPI error on failure. @*/ int MPIR_Type_blockindexed(int count, int blocklength, const void *displacement_array, int dispinbytes, MPI_Datatype oldtype, MPI_Datatype * newtype) { int mpi_errno = MPI_SUCCESS, i; int is_builtin, old_is_contig; MPI_Aint contig_count; MPI_Aint el_sz; MPI_Datatype el_type; MPI_Aint old_lb, old_ub, old_extent, old_true_lb, old_true_ub; MPI_Aint min_lb = 0, max_ub = 0, eff_disp; MPIR_Datatype *new_dtp; if (count == 0) return MPII_Type_zerolen(newtype); /* allocate new datatype object and handle */ new_dtp = (MPIR_Datatype *) MPIR_Handle_obj_alloc(&MPIR_Datatype_mem); /* --BEGIN ERROR HANDLING-- */ if (!new_dtp) { mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, "MPIR_Type_vector", __LINE__, MPI_ERR_OTHER, "**nomem", 0); return mpi_errno; } /* --END ERROR HANDLING-- */ /* handle is filled in by MPIR_Handle_obj_alloc() */ MPIR_Object_set_ref(new_dtp, 1); new_dtp->is_committed = 0; new_dtp->attributes = NULL; new_dtp->name[0] = 0; new_dtp->contents = NULL; new_dtp->dataloop = NULL; new_dtp->dataloop_size = -1; is_builtin = (HANDLE_GET_KIND(oldtype) == HANDLE_KIND_BUILTIN); if (is_builtin) { el_sz = (MPI_Aint) MPIR_Datatype_get_basic_size(oldtype); el_type = oldtype; old_lb = 0; old_true_lb = 0; old_ub = el_sz; old_true_ub = el_sz; old_extent = el_sz; old_is_contig = 1; new_dtp->size = (MPI_Aint) count *(MPI_Aint) blocklength *el_sz; new_dtp->has_sticky_lb = 0; new_dtp->has_sticky_ub = 0; new_dtp->alignsize = el_sz; /* ??? */ new_dtp->n_builtin_elements = count * blocklength; new_dtp->builtin_element_size = el_sz; new_dtp->basic_type = el_type; new_dtp->max_contig_blocks = count; } else { /* user-defined base type (oldtype) */ MPIR_Datatype *old_dtp; MPIR_Datatype_get_ptr(oldtype, old_dtp); el_sz = old_dtp->builtin_element_size; el_type = old_dtp->basic_type; old_lb = old_dtp->lb; old_true_lb = old_dtp->true_lb; old_ub = old_dtp->ub; old_true_ub = old_dtp->true_ub; old_extent = old_dtp->extent; MPIR_Datatype_is_contig(oldtype, &old_is_contig); new_dtp->size = (MPI_Aint) count *(MPI_Aint) blocklength *(MPI_Aint) old_dtp->size; new_dtp->has_sticky_lb = old_dtp->has_sticky_lb; new_dtp->has_sticky_ub = old_dtp->has_sticky_ub; new_dtp->alignsize = old_dtp->alignsize; new_dtp->n_builtin_elements = count * blocklength * old_dtp->n_builtin_elements; new_dtp->builtin_element_size = el_sz; new_dtp->basic_type = el_type; new_dtp->max_contig_blocks = old_dtp->max_contig_blocks * count * blocklength; } /* priming for loop */ eff_disp = (dispinbytes) ? ((MPI_Aint *) displacement_array)[0] : (((MPI_Aint) ((int *) displacement_array)[0]) * old_extent); MPII_DATATYPE_BLOCK_LB_UB((MPI_Aint) blocklength, eff_disp, old_lb, old_ub, old_extent, min_lb, max_ub); /* determine new min lb and max ub */ for (i = 1; i < count; i++) { MPI_Aint tmp_lb, tmp_ub; eff_disp = (dispinbytes) ? ((MPI_Aint *) displacement_array)[i] : (((MPI_Aint) ((int *) displacement_array)[i]) * old_extent); MPII_DATATYPE_BLOCK_LB_UB((MPI_Aint) blocklength, eff_disp, old_lb, old_ub, old_extent, tmp_lb, tmp_ub); if (tmp_lb < min_lb) min_lb = tmp_lb; if (tmp_ub > max_ub) max_ub = tmp_ub; } new_dtp->lb = min_lb; new_dtp->ub = max_ub; new_dtp->true_lb = min_lb + (old_true_lb - old_lb); new_dtp->true_ub = max_ub + (old_true_ub - old_ub); new_dtp->extent = max_ub - min_lb; /* new type is contig for N types if it is all one big block, * its size and extent are the same, and the old type was also * contiguous. */ new_dtp->is_contig = 0; if (old_is_contig) { contig_count = MPII_Datatype_blockindexed_count_contig(count, blocklength, displacement_array, dispinbytes, old_extent); new_dtp->max_contig_blocks = contig_count; if ((contig_count == 1) && ((MPI_Aint) new_dtp->size == new_dtp->extent)) { new_dtp->is_contig = 1; } } *newtype = new_dtp->handle; return mpi_errno; }