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

📄 dataloop_create_struct.c

📁 fortran并行计算包
💻 C
📖 第 1 页 / 共 2 页
字号:
/* -*- Mode: C; c-basic-offset:4 ; -*- *//* *  (C) 2001 by Argonne National Laboratory. *      See COPYRIGHT in top-level directory. */#include "./dataloop.h"#ifndef PREPEND_PREFIX#error "You must explicitly include a header that sets the PREPEND_PREFIX and includes dataloop_parts.h"#endifstatic int DLOOP_Dataloop_create_struct_memory_error(void);static int DLOOP_Dataloop_create_unique_type_struct(int count,						    int *blklens,						    MPI_Aint *disps,						    DLOOP_Type *oldtypes,						    int type_pos,						    DLOOP_Dataloop **dlp_p,						    int *dlsz_p,						    int *dldepth_p,						    int flag);static int DLOOP_Dataloop_create_basic_all_bytes_struct(	       int count,	       int *blklens,	       MPI_Aint *disps,	       DLOOP_Type *oldtypes,	       DLOOP_Dataloop **dlp_p,	       int *dlsz_p,	       int *dldepth_p,	       int flag);static int DLOOP_Dataloop_create_flattened_struct(int count,						  int *blklens,						  MPI_Aint *disps,						  DLOOP_Type *oldtypes,						  DLOOP_Dataloop **dlp_p,						  int *dlsz_p,						  int *dldepth_p,						  int flag);/*@  Dataloop_create_struct - create the dataloop representation for a  struct datatype  Input Parameters:+ count - number of blocks in vector. blklens - number of elements in each block. disps - offsets of blocks from start of type in bytes- oldtypes - types (using handle) of datatypes on which vector is based  Output Parameters:+ dlp_p - pointer to address in which to place pointer to new dataloop- dlsz_p - pointer to address in which to place size of new dataloop  Return Value:  0 on success, -1 on failure.  Notes:  This function relies on others, like Dataloop_create_indexed, to create  types in some cases. This call (like all the rest) takes int blklens  and MPI_Aint displacements, so it's possible to overflow when working  with a particularly large struct type in some cases. This isn't detected  or corrected in this code at this time.@*/int PREPEND_PREFIX(Dataloop_create_struct)(int count,					   int *blklens,					   MPI_Aint *disps,					   DLOOP_Type *oldtypes,					   DLOOP_Dataloop **dlp_p,					   int *dlsz_p,					   int *dldepth_p,					   int flag){    int err, i, nr_basics = 0, nr_derived = 0, type_pos = 0;    DLOOP_Type first_basic = MPI_DATATYPE_NULL,	first_derived = MPI_DATATYPE_NULL;    /* variables used in general case only */    int loop_idx, new_loop_sz, new_loop_depth;    int old_loop_sz = 0, old_loop_depth = 0;    DLOOP_Dataloop *new_dlp, *curpos;    /* if count is zero, handle with contig code, call it a int */    if (count == 0)    {	err = PREPEND_PREFIX(Dataloop_create_contiguous)(0,							 MPI_INT,							 dlp_p,							 dlsz_p,							 dldepth_p,							 flag);	return err;    }    /* browse the old types and characterize */    for (i=0; i < count; i++)    {	/* ignore type elements with a zero blklen */	if (blklens[i] == 0) continue;	if (oldtypes[i] != MPI_LB && oldtypes[i] != MPI_UB)	{	    int is_builtin;	    is_builtin =		(DLOOP_Handle_hasloop_macro(oldtypes[i])) ? 0 : 1;	    if (is_builtin)	    {		if (nr_basics == 0)		{		    first_basic = oldtypes[i];		    type_pos = i;		}		else if (oldtypes[i] != first_basic)		{		    first_basic = MPI_DATATYPE_NULL;		}		nr_basics++;	    }	    else /* derived type */	    {		if (nr_derived == 0)		{		    first_derived = oldtypes[i];		    type_pos = i;		}		else if (oldtypes[i] != first_derived)		{		    first_derived = MPI_DATATYPE_NULL;		}		nr_derived++;	    }	}    }    /* note on optimizations:     *     * because LB, UB, and extent calculations are handled as part of     * the Datatype, we can safely ignore them in all our calculations     * here.     */    /* optimization:     *     * if there were only MPI_LBs and MPI_UBs in the struct type,     * treat it as a zero-element contiguous (just as count == 0).     */    if (nr_basics == 0 && nr_derived == 0)    {	err = PREPEND_PREFIX(Dataloop_create_contiguous)(0,							 MPI_INT,							 dlp_p,							 dlsz_p,							 dldepth_p,							 flag);	return err;    }    /* optimization:     *     * if there is only one unique instance of a type in the struct, treat it     * as a blockindexed type.     *     * notes:     *     * if the displacement happens to be zero, the blockindexed code will     * optimize this into a contig.     */    if (nr_basics + nr_derived == 1)    {	/* type_pos is index to only real type in array */	err = PREPEND_PREFIX(Dataloop_create_blockindexed)	    (1, /* count */	     blklens[type_pos],	     &disps[type_pos],	     1, /* displacement in bytes */	     oldtypes[type_pos],	     dlp_p,	     dlsz_p,	     dldepth_p,	     flag);	return err;    }    /* optimization:     *     * if there only one unique type (more than one instance) in the     * struct, treat it as an indexed type.     *     * notes:     *      * this will apply to a single type with an LB/UB, as those     * are handled elsewhere.     *     */    if (((nr_derived == 0) && (first_basic != MPI_DATATYPE_NULL)) ||	((nr_basics == 0) && (first_derived != MPI_DATATYPE_NULL)))    {	return DLOOP_Dataloop_create_unique_type_struct(count,							blklens,							disps,							oldtypes,							type_pos,							dlp_p,							dlsz_p,							dldepth_p,							flag);    }    /* optimization:     *     * if there are no derived types and caller indicated either a     * homogeneous system or the "all bytes" conversion, convert     * everything to bytes and use an indexed type.     */    if (nr_derived == 0 && ((flag == DLOOP_DATALOOP_HOMOGENEOUS) ||			    (flag == DLOOP_DATALOOP_ALL_BYTES)))    {	return DLOOP_Dataloop_create_basic_all_bytes_struct(count,							    blklens,							    disps,							    oldtypes,							    dlp_p,							    dlsz_p,							    dldepth_p,							    flag);    }    /* optimization:     *     * if caller asked for homogeneous or all bytes representation,     * flatten the type and store it as an indexed type so that     * there are no branches in the dataloop tree.     */    if ((flag == DLOOP_DATALOOP_HOMOGENEOUS) ||	     (flag == DLOOP_DATALOOP_ALL_BYTES))    {	return DLOOP_Dataloop_create_flattened_struct(count,						      blklens,						      disps,						      oldtypes,						      dlp_p,						      dlsz_p,						      dldepth_p,						      flag);    }    /* scan through types and gather derived type info */    for (i=0; i < count; i++)    {	/* ignore type elements with a zero blklen */	if (blklens[i] == 0) continue;	if (DLOOP_Handle_hasloop_macro(oldtypes[i]))	{	    int tmp_loop_depth, tmp_loop_sz;	    DLOOP_Handle_get_loopdepth_macro(oldtypes[i], tmp_loop_depth, flag);	    DLOOP_Handle_get_loopsize_macro(oldtypes[i], tmp_loop_sz, flag);	    if (tmp_loop_depth > old_loop_depth)	    {		old_loop_depth = tmp_loop_depth;	    }	    old_loop_sz += tmp_loop_sz;	}    }        /* general case below: 2 or more distinct types that are either     * basics or derived, and for which we want to preserve the types     * themselves.     */        if (nr_basics > 0)    {	/* basics introduce an extra level of depth, so if our new depth	 * must be at least 2 if there are basics.	 */	new_loop_depth = ((old_loop_depth+1) > 2) ? (old_loop_depth+1) : 2;    }    else    {	new_loop_depth = old_loop_depth + 1;    }    PREPEND_PREFIX(Dataloop_struct_alloc)((DLOOP_Count) nr_basics + nr_derived,					  old_loop_sz,					  nr_basics,					  &curpos,					  &new_dlp,					  &new_loop_sz);    /* --BEGIN ERROR HANDLING-- */    if (!new_dlp)    {	return DLOOP_Dataloop_create_struct_memory_error();    }    /* --END ERROR HANDLING-- */    new_dlp->kind = DLOOP_KIND_STRUCT;    new_dlp->el_size = -1; /* not valid for struct */    new_dlp->el_extent = -1; /* not valid for struct; see el_extent_array */    new_dlp->el_type = MPI_DATATYPE_NULL; /* not valid for struct */    new_dlp->loop_params.s_t.count = (DLOOP_Count) nr_basics + nr_derived;    /* note: curpos points to first byte in "old dataloop" region of     * newly allocated space.     */    for (i=0, loop_idx = 0; i < count; i++)    {	int is_builtin;	/* ignore type elements with a zero blklen */	if (blklens[i] == 0) continue;	is_builtin = (DLOOP_Handle_hasloop_macro(oldtypes[i])) ? 0 : 1;	if (is_builtin)	{	    DLOOP_Dataloop *dummy_dlp;	    int dummy_sz, dummy_depth;	    /* LBs and UBs already taken care of -- skip them */	    if (oldtypes[i] == MPI_LB || oldtypes[i] == MPI_UB)	    {		continue;	    }	    /* build a contig dataloop for this basic and point to that

⌨️ 快捷键说明

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