⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpid_type_struct.c

📁 刚才是说明 现在是安装程序在 LINUX环境下进行编程的MPICH安装文件
💻 C
📖 第 1 页 / 共 2 页
字号:
/* -*- Mode: C; c-basic-offset:4 ; -*- *//* *  (C) 2001 by Argonne National Laboratory. *      See COPYRIGHT in top-level directory. */#include <mpiimpl.h>#include <mpid_dataloop.h>#include <stdlib.h>#include <assert.h>#include <limits.h>#undef MPID_STRUCT_FLATTEN_DEBUG#undef MPID_STRUCT_DEBUGint MPID_Type_struct_alignsize(int count,			       MPI_Datatype *oldtype_array);int MPID_Type_struct_alignsize(int count,			       MPI_Datatype *oldtype_array){    int i, max_alignsize = 0, tmp_alignsize;    for (i=0; i < count; i++) {	/* shouldn't be called with an LB or UB, but we'll handle it nicely */	if (oldtype_array[i] == MPI_LB || oldtype_array[i] == MPI_UB) continue;	else if (HANDLE_GET_KIND(oldtype_array[i]) == HANDLE_KIND_BUILTIN) {	    tmp_alignsize = MPID_Datatype_get_basic_size(oldtype_array[i]);	}	else {	    MPID_Datatype *dtp;	    	    MPID_Datatype_get_ptr(oldtype_array[i], dtp);	    tmp_alignsize = dtp->alignsize;	}	if (max_alignsize < tmp_alignsize) max_alignsize = tmp_alignsize;    }#ifdef HAVE_MAX_STRUCT_ALIGNMENT    if (max_alignsize > HAVE_MAX_STRUCT_ALIGNMENT) max_alignsize = HAVE_MAX_STRUCT_ALIGNMENT;#endif    /* if we didn't calculate a maximum struct alignment (above), then the     * alignment was either "largest", in which case we just use what we found,     * or "unknown", in which case what we found is as good a guess as any.     */    return max_alignsize;}/*@  MPID_Type_struct - create a struct datatype   Input Parameters:+ count - number of blocks in vector. blocklength_array - number of elements in each block. displacement_array - offsets of blocks from start of type in bytes- oldtype_array - types (using handle) of datatypes on which vector is based  Output Parameters:. newtype - handle of new struct datatype  Return Value:  0 on success, -1 on failure.  This version relies on other MPID_Type routines in order to create the  final type.  The resulting type will bear little resemblance to what was passed in, and  currently get contents/envelope would not work.@*//* * THIS VERSION CONVERTS THE STRUCT INTO AN HINDEXED, SO IT'S ONLY GOOD FOR * HOMOGENOUS SYSTEMS!!! */int MPID_Type_struct(int count,		     int *blocklength_array,		     MPI_Aint *displacement_array,		     MPI_Datatype *oldtype_array,		     MPI_Datatype *newtype){    int mpi_errno = MPI_SUCCESS;    int i, nr_real_types = 0, all_basics = 1, all_same = 1, has_lb_builtin = 0, has_ub_builtin = 0;    MPID_Datatype *new_dtp, *old_dtp;#ifdef MPID_STRUCT_DEBUG    MPIDI_Datatype_printf(oldtype_array[0], 1, displacement_array[0], blocklength_array[0], 1);    for (i=1; i < count; i++) {	MPIDI_Datatype_printf(oldtype_array[i], 1, displacement_array[i], blocklength_array[i], 0);    }#endif    if (count == 1) {	/* simplest case: count == 1 */	/* NOTE: this could be done with a contig with an LB I think? */	mpi_errno = MPID_Type_indexed(count,				      blocklength_array,				      displacement_array,				      1, /* displacement in bytes */				      *oldtype_array,				      newtype);#ifdef MPID_STRUCT_DEBUG	MPIDI_Datatype_printf(*newtype, 0, 0, 1, 0);#endif	return mpi_errno;    }        if (*oldtype_array == MPI_LB) has_lb_builtin = 1;    else if (*oldtype_array == MPI_UB) has_ub_builtin = 1;    else if (HANDLE_GET_KIND(*oldtype_array) != HANDLE_KIND_BUILTIN) {	all_basics = 0;	nr_real_types = 1;    }    else {	nr_real_types = 1;    }    /* have a quick look at the types to see if there are any easy simplifications     * that we can make.     */    for (i=1; i < count; i++) {	if (oldtype_array[i] == MPI_LB) has_lb_builtin = 1;	else if (oldtype_array[i] == MPI_UB) has_ub_builtin = 1;	else if (HANDLE_GET_KIND(oldtype_array[i]) != HANDLE_KIND_BUILTIN) {	    all_basics = 0;	    nr_real_types++;	}	else /* builtin that isn't an LB or UB */ nr_real_types++;	if (oldtype_array[i] != *oldtype_array) all_same = 0;    }    if (all_same) {	/* they used the same type every time; this is just an hindexed again */	mpi_errno = MPID_Type_indexed(count,				      blocklength_array,				      displacement_array,				      1, /* displacement in bytes */				      *oldtype_array,				      newtype);	/* 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;    }    else if (all_basics && !has_lb_builtin && !has_ub_builtin) {	/* no derived types and no ub/lb, but not all the same -- just convert	 * everything to bytes.	 */	int *tmp_blocklength_array, alignsize, epsilon;		tmp_blocklength_array = (int *) MPIU_Malloc(count * sizeof(int));	for (i=0; i < count; i++) {	    int sz = MPID_Datatype_get_basic_size(oldtype_array[i]);	    tmp_blocklength_array[i] = sz * blocklength_array[i];	}	mpi_errno = MPID_Type_indexed(count,				      tmp_blocklength_array,				      displacement_array,				      1, /* displacement in bytes */				      MPI_BYTE,				      newtype);	MPIU_Free(tmp_blocklength_array);	/* 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; /* not all the same size */#ifdef MPID_STRUCT_DEBUG	MPIDI_Datatype_printf(*newtype, 0, 0, 1, 0);#endif	return mpi_errno;    } /* end of all basics w/out lb or ub case */    /* TODO: Catch case of a single basic with an LB and/or UB; this can be done     * with a contig followed by an adjustment of the LB and UB, which would be     * simpler to process than the indexed that we use below.     */    else if (all_basics) {	/* There are only basics, but there are LBs and/or UBs that we need to	 * strip out.  So we convert to MPI_BYTEs as before, pull out the LBs and	 * UBs, and then adjust the LB/UB as needed afterwards.	 */	int tmp_idx = 0, *tmp_blocklength_array, found_lb = 0, found_ub = 0;	MPI_Aint lb_disp = 0, ub_disp = 0, *tmp_displacement_array;	/* don't bother to figure out exactly how much space we really need; use	 * count as an upper bound instead.	 */	tmp_blocklength_array  = (int *) MPIU_Malloc(count * sizeof(int));	tmp_displacement_array = (MPI_Aint *) MPIU_Malloc(count * sizeof(MPI_Aint));	/* pass through all the types:	 * - find the smallest LB	 * - find the largest UB	 * - create the tmp blocklength and displacemment arrays	 * - get tmp count	 */	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 {		int sz = MPID_Datatype_get_basic_size(oldtype_array[i]);		tmp_blocklength_array[tmp_idx]  = sz * blocklength_array[i];		tmp_displacement_array[tmp_idx] = displacement_array[i];		tmp_idx++;	    } 	}	mpi_errno = MPID_Type_indexed(tmp_idx,				      tmp_blocklength_array,				      tmp_displacement_array,				      1, /* displacement in bytes */				      MPI_BYTE,				      newtype);		MPIU_Free(tmp_blocklength_array);	MPIU_Free(tmp_displacement_array);	if (mpi_errno != MPI_SUCCESS) return mpi_errno;	/* deal with the LB and/or UB */	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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -