📄 mpid_type_struct.c
字号:
/* TODO: don't bother with alignsize because of the lb/ub (?) */#ifdef MPID_STRUCT_DEBUG MPIDI_Datatype_printf(*newtype, 0, 0, 1, 0);#endif return mpi_errno; } /* end of all basics w/ lb and/or ub case */ else if (nr_real_types == 1) { /* There's exactly one derived type in the struct. * * steps: * - find the locations of the UB and LB, index of actual type * - ... * * NOTE: if displacement of type is zero, we can dup and adjust * lb/ub/extent. otherwise we need to deal with the displacement. * the easiest way to do that is with an byte indexed type again. */ int found_lb = 0, found_ub = 0, real_type_idx = -1; MPI_Aint lb_disp = -1, ub_disp = -1; for (i=0; i < count; i++) { if (oldtype_array[i] == MPI_LB) { if (!found_lb) { found_lb = 1; lb_disp = displacement_array[i]; } else if (displacement_array[i] < lb_disp) lb_disp = displacement_array[i]; } else if (oldtype_array[i] == MPI_UB) { if (!found_ub) { found_ub = 1; ub_disp = displacement_array[i]; } else if (displacement_array[i] > ub_disp) ub_disp = displacement_array[i]; } else real_type_idx = i; } if (displacement_array[real_type_idx] == 0 && blocklength_array[real_type_idx] == 1) { mpi_errno = MPID_Type_dup(oldtype_array[real_type_idx], newtype); } else if (displacement_array[real_type_idx] == 0) { mpi_errno = MPID_Type_contiguous(blocklength_array[real_type_idx], oldtype_array[real_type_idx], newtype); } else { mpi_errno = MPID_Type_indexed(1, &blocklength_array[real_type_idx], &displacement_array[real_type_idx], 1, oldtype_array[real_type_idx], newtype); } if (mpi_errno != MPI_SUCCESS) return mpi_errno; MPID_Datatype_get_ptr(*newtype, new_dtp); MPID_Datatype_get_ptr(oldtype_array[real_type_idx], old_dtp); new_dtp->is_committed = 0; /* especially for dup'd type */ if (found_lb) { new_dtp->has_sticky_lb = 1; if (old_dtp->has_sticky_lb && old_dtp->lb < lb_disp) lb_disp = old_dtp->lb; new_dtp->lb = lb_disp; } if (found_ub) { new_dtp->has_sticky_ub = 1; if (old_dtp->has_sticky_ub && old_dtp->ub > ub_disp) ub_disp = old_dtp->ub; new_dtp->ub = ub_disp; } new_dtp->extent = new_dtp->ub - new_dtp->lb; /* alignsize and padding should be ok in this case */#ifdef MPID_STRUCT_DEBUG MPIDI_Datatype_printf(*newtype, 0, 0, 1, 0);#endif return mpi_errno; } /* end of single derived type case */ else { int nr_pieces = 0, first = 0, last, bytes, found_lb = 0, found_ub = 0, epsilon, alignsize; int *tmp_blocklength_array; MPI_Aint *tmp_displacement_array, lb_disp = 0, ub_disp = 0; MPID_IOV *iov_array; MPID_Segment *segp; /* General case: more than one type, not all of which are basics. * * We're going to flatten the whole thing into a collection * of contiguous pieces and make an hindexed out of that. * * Three passes (roughly): * - First figure out how many pieces there are going to be. * - Allocate and fill in arrays of extents for type. * - Recalculate the number of elements (basics) * */ for (i=0; i < count; i++) { int tmp_pieces = 0, tmp_lb, tmp_ub; if (oldtype_array[i] == MPI_LB) { if (!found_lb) { found_lb = 1; lb_disp = displacement_array[i]; } else if (displacement_array[i] < lb_disp) lb_disp = displacement_array[i]; } else if (oldtype_array[i] == MPI_UB) { if (!found_ub) { found_ub = 1; ub_disp = displacement_array[i]; } else if (displacement_array[i] > ub_disp) ub_disp = displacement_array[i]; } else if (HANDLE_GET_KIND(oldtype_array[i]) == HANDLE_KIND_BUILTIN) tmp_pieces = 1; else { MPID_Datatype_get_ptr(oldtype_array[i], old_dtp); /* calculate lb and ub of this type; see mpid_datatype.h */ MPID_DATATYPE_BLOCK_LB_UB(blocklength_array[i], displacement_array[i], old_dtp->lb, old_dtp->ub, old_dtp->extent, tmp_lb, tmp_ub); tmp_pieces = old_dtp->n_elements; if (old_dtp->has_sticky_lb) { if (!found_lb) { found_lb = 1; lb_disp = tmp_lb; } else if (tmp_lb < lb_disp) lb_disp = tmp_lb; } if (old_dtp->has_sticky_ub) { if (!found_ub) { found_ub = 1; ub_disp = tmp_ub; } else if (tmp_ub > ub_disp) ub_disp = tmp_ub; } } /* nr_pieces is an upper bound only; for example, a contig will only * take up one slot regardless of the blocklength */ nr_pieces += tmp_pieces * blocklength_array[i]; } nr_pieces += 2; /* TEMPORARY SANITY CHECK!!! */ iov_array = (MPID_IOV *) MPIU_Malloc(nr_pieces * sizeof(MPID_IOV)); if (iov_array == NULL) assert(0); tmp_blocklength_array = (int *) MPIU_Malloc(nr_pieces * sizeof(int)); if (tmp_blocklength_array == NULL) assert(0); tmp_displacement_array = (MPI_Aint *) MPIU_Malloc(nr_pieces * sizeof(MPI_Aint)); if (tmp_displacement_array == NULL) assert(0); segp = MPID_Segment_alloc(); first = 0; for (i=0; i < count; i++) { /* we're going to use the segment code to flatten the type. * we put in our displacement as the buffer location, and use * the blocklength as the count value to get N contiguous copies * of the type. * * Note that we're going to get back values in bytes, so that will * be our new element type. */ if (oldtype_array[i] != MPI_UB && oldtype_array[i] != MPI_LB) { MPID_Segment_init((char *) displacement_array[i], blocklength_array[i], oldtype_array[i], segp); last = nr_pieces - first; bytes = INT_MAX; /* TODO: CREATE MANIPULATION ROUTINES THAT TAKE THE LEN AND DISP * ARRAYS AND FILL THEM IN DIRECTLY. */ MPID_Segment_pack_vector(segp, 0, &bytes, /* don't care, just want it to go */ &iov_array[first], &last); first += last; } } nr_pieces = first;#ifdef MPID_STRUCT_FLATTEN_DEBUG MPIU_dbg_printf("--- start of flattened type ---\n"); for (i=0; i < nr_pieces; i++) { MPIU_dbg_printf("a[%d] = (%d, %d)\n", i, iov_array[i].MPID_IOV_BUF, iov_array[i].MPID_IOV_LEN); } MPIU_dbg_printf("--- end of flattened type ---\n");#endif for (i=0; i < nr_pieces; i++) { tmp_blocklength_array[i] = iov_array[i].MPID_IOV_LEN; tmp_displacement_array[i] = (MPI_Aint) iov_array[i].MPID_IOV_BUF; } MPID_Segment_free(segp); MPIU_Free(iov_array); mpi_errno = MPID_Type_indexed(nr_pieces, tmp_blocklength_array, tmp_displacement_array, 1, MPI_BYTE, newtype); if (mpi_errno != MPI_SUCCESS) assert(0); MPIU_Free(tmp_displacement_array); MPIU_Free(tmp_blocklength_array); MPID_Datatype_get_ptr(*newtype, new_dtp); if (found_lb) { new_dtp->has_sticky_lb = 1; new_dtp->lb = lb_disp; } if (found_ub) { new_dtp->has_sticky_ub = 1; new_dtp->ub = ub_disp; } new_dtp->extent = new_dtp->ub - new_dtp->lb; if (!found_lb && !found_ub) { /* account for padding */ MPID_Datatype_get_ptr(*newtype, new_dtp); alignsize = MPID_Type_struct_alignsize(count, oldtype_array); new_dtp->alignsize = alignsize; epsilon = new_dtp->extent % alignsize; if (epsilon) { new_dtp->ub += (alignsize - epsilon); new_dtp->extent = new_dtp->ub - new_dtp->lb; } } new_dtp->element_size = -1;#ifdef MPID_STRUCT_DEBUG MPIDI_Datatype_printf(*newtype, 0, 0, 1, 0);#endif return mpi_errno; } /* end of general case */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -