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

📄 segment.c

📁 fortran并行计算包
💻 C
📖 第 1 页 / 共 2 页
字号:
	    DLOOP_dbg_printf("\thit leaf; cur_sp=%d, elmp=%x, piece_sz=%d\n",			     cur_sp,		             (unsigned) cur_elmp, myblocks * local_el_size);#endif	    /* enforce the last parameter if necessary by reducing myblocks */	    if (last != SEGMENT_IGNORE_LAST &&		(stream_off + (myblocks * stream_el_size) > last))	    {		myblocks = ((last - stream_off) / stream_el_size);#ifdef DLOOP_DEBUG_MANIPULATE		DLOOP_dbg_printf("\tpartial block count=%d (%d bytes)\n",				 myblocks,                                 (int) myblocks * stream_el_size);#endif		if (myblocks == 0) {		    DLOOP_SEGMENT_SAVE_LOCAL_VALUES;		    return;		}	    }	    /* call piecefn to perform data manipulation */	    switch (piecefn_type) {		case PF_NULL:		    piecefn_indicated_exit = 0;#ifdef DLOOP_DEBUG_MANIPULATE		    DLOOP_dbg_printf("\tNULL piecefn for this piece\n");#endif		    break;		case PF_CONTIG:		    DLOOP_Assert(myblocks <= cur_elmp->curblock);		    piecefn_indicated_exit =			contigfn(&myblocks,				 el_type,				 cur_elmp->curoffset, /* relative to segp->ptr */				 segp->ptr, /* start of buffer (from segment) */				 pieceparams);		    break;		case PF_VECTOR:		    piecefn_indicated_exit =			vectorfn(&myblocks,				 cur_elmp->curcount,				 cur_elmp->orig_block,				 cur_elmp->loop_p->loop_params.v_t.stride,				 el_type,				 cur_elmp->curoffset,				 segp->ptr,				 pieceparams);		    break;		case PF_BLOCKINDEXED:		    piecefn_indicated_exit =			blkidxfn(&myblocks,				 cur_elmp->curcount,				 cur_elmp->orig_block,				 cur_elmp->loop_p->loop_params.bi_t.offset_array,				 el_type,				 cur_elmp->orig_offset, /* blkidxfn adds offset */				 segp->ptr,				 pieceparams);				 		    break;		case PF_INDEXED:		    piecefn_indicated_exit =			indexfn(&myblocks,				cur_elmp->curcount,				cur_elmp->loop_p->loop_params.i_t.blocksize_array,				cur_elmp->loop_p->loop_params.i_t.offset_array,				el_type,				cur_elmp->orig_offset, /* indexfn adds offset value */				segp->ptr,				pieceparams);		    break;	    }	    /* update local values based on piecefn returns (myblocks and	     * piecefn_indicated_exit)	     */	    DLOOP_Assert(piecefn_indicated_exit >= 0);	    DLOOP_Assert(myblocks >= 0);	    stream_off += myblocks * stream_el_size;	    /* myblocks of 0 or less than cur_elmp->curblock indicates	     * that we should stop processing and return.	     */	    if (myblocks == 0) {		DLOOP_SEGMENT_SAVE_LOCAL_VALUES;		return;	    }	    else if (myblocks < cur_elmp->curblock) {		cur_elmp->curoffset += myblocks * local_el_size;		cur_elmp->curblock  -= myblocks;		DLOOP_SEGMENT_SAVE_LOCAL_VALUES;		return;	    }	    else /* myblocks >= cur_elmp->curblock */ {		int count_index = 0;		/* this assumes we're either *just* processing the last parts		 * of the current block, or we're processing as many blocks as		 * we like starting at the beginning of one.		 */		switch (cur_elmp->loop_p->kind & DLOOP_KIND_MASK) {		    case DLOOP_KIND_INDEXED:			while (myblocks > 0 && myblocks >= cur_elmp->curblock) {			    myblocks -= cur_elmp->curblock;			    cur_elmp->curcount--;			    DLOOP_Assert(cur_elmp->curcount >= 0);			    count_index = cur_elmp->orig_count -				cur_elmp->curcount;			    cur_elmp->curblock =				DLOOP_STACKELM_INDEXED_BLOCKSIZE(cur_elmp,								 count_index);			}			if (cur_elmp->curcount == 0) {			    /* don't bother to fill in values; we're popping anyway */			    DLOOP_Assert(myblocks == 0);			    DLOOP_SEGMENT_POP_AND_MAYBE_EXIT;			}			else {			    cur_elmp->orig_block = cur_elmp->curblock;			    cur_elmp->curoffset  = cur_elmp->orig_offset +				DLOOP_STACKELM_INDEXED_OFFSET(cur_elmp,							      count_index);			    			    cur_elmp->curblock  -= myblocks;			    cur_elmp->curoffset += myblocks * local_el_size;			}			break;		    case DLOOP_KIND_VECTOR:			/* this math relies on assertions at top of code block */			cur_elmp->curcount -= myblocks / cur_elmp->curblock;			if (cur_elmp->curcount == 0) {			    DLOOP_Assert(myblocks % cur_elmp->curblock == 0);			    DLOOP_SEGMENT_POP_AND_MAYBE_EXIT;			}			else {			    /* this math relies on assertions at top of code			     * block			     */			    cur_elmp->curblock = cur_elmp->orig_block -				(myblocks % cur_elmp->curblock);			    /* new offset = original offset +			     *              stride * whole blocks +			     *              leftover bytes			     */			    cur_elmp->curoffset = cur_elmp->orig_offset +				((cur_elmp->orig_count - cur_elmp->curcount) *				 cur_elmp->loop_p->loop_params.v_t.stride) +				((cur_elmp->orig_block - cur_elmp->curblock) *				 local_el_size);			}			break;		    case DLOOP_KIND_CONTIG:			/* contigs that reach this point have always been			 * completely processed			 */			DLOOP_Assert(myblocks == cur_elmp->curblock &&			       cur_elmp->curcount == 1);			DLOOP_SEGMENT_POP_AND_MAYBE_EXIT;			break;		    case DLOOP_KIND_BLOCKINDEXED:			while (myblocks > 0 && myblocks >= cur_elmp->curblock)			{			    myblocks -= cur_elmp->curblock;			    cur_elmp->curcount--;			    DLOOP_Assert(cur_elmp->curcount >= 0);			    count_index = cur_elmp->orig_count -				cur_elmp->curcount;			    cur_elmp->curblock = cur_elmp->orig_block;			}			if (cur_elmp->curcount == 0) {			    /* popping */			    DLOOP_Assert(myblocks == 0);			    DLOOP_SEGMENT_POP_AND_MAYBE_EXIT;			}			else {			    /* cur_elmp->orig_block = cur_elmp->curblock; */			    cur_elmp->curoffset = cur_elmp->orig_offset +				DLOOP_STACKELM_BLOCKINDEXED_OFFSET(cur_elmp,								   count_index);			    cur_elmp->curblock  -= myblocks;			    cur_elmp->curoffset += myblocks * local_el_size;			}			break;		}	    }	    if (piecefn_indicated_exit) {		/* piece function indicated that we should quit processing */		DLOOP_SEGMENT_SAVE_LOCAL_VALUES;		return;	    }	} /* end of if leaf */	else if (cur_elmp->curblock == 0) {#ifdef DLOOP_DEBUG_MANIPULATE	    DLOOP_dbg_printf("\thit end of block; elmp=%x [%d]\n",			    (unsigned) cur_elmp, cur_sp);#endif	    cur_elmp->curcount--;	    /* new block.  for indexed and struct reset orig_block.	     * reset curblock for all types	     */	    switch (cur_elmp->loop_p->kind & DLOOP_KIND_MASK) {		case DLOOP_KIND_CONTIG:		case DLOOP_KIND_VECTOR:		case DLOOP_KIND_BLOCKINDEXED:		    break;		case DLOOP_KIND_INDEXED:		    cur_elmp->orig_block =			DLOOP_STACKELM_INDEXED_BLOCKSIZE(cur_elmp, cur_elmp->curcount ? cur_elmp->orig_count - cur_elmp->curcount : 0);		    break;		case DLOOP_KIND_STRUCT:		    cur_elmp->orig_block =			DLOOP_STACKELM_STRUCT_BLOCKSIZE(cur_elmp, cur_elmp->curcount ? cur_elmp->orig_count - cur_elmp->curcount : 0);		    break;		default:		    /* --BEGIN ERROR HANDLING-- */		    DLOOP_Assert(0);		    break;		    /* --END ERROR HANDLING-- */	    }	    cur_elmp->curblock = cur_elmp->orig_block;	    if (cur_elmp->curcount == 0) {#ifdef DLOOP_DEBUG_MANIPULATE		DLOOP_dbg_printf("\talso hit end of count; elmp=%x [%d]\n",				(unsigned) cur_elmp, cur_sp);#endif		DLOOP_SEGMENT_POP_AND_MAYBE_EXIT;	    }	}	else /* push the stackelm */ {	    DLOOP_Dataloop_stackelm *next_elmp;	    int count_index, block_index;	    count_index = cur_elmp->orig_count - cur_elmp->curcount;	    block_index = cur_elmp->orig_block - cur_elmp->curblock;	    /* reload the next stackelm if necessary */	    next_elmp = &(segp->stackelm[cur_sp + 1]);	    if (cur_elmp->may_require_reloading) {		DLOOP_Dataloop *load_dlp = NULL;		switch (cur_elmp->loop_p->kind & DLOOP_KIND_MASK) {		    case DLOOP_KIND_CONTIG:		    case DLOOP_KIND_VECTOR:		    case DLOOP_KIND_BLOCKINDEXED:		    case DLOOP_KIND_INDEXED:			load_dlp = cur_elmp->loop_p->loop_params.cm_t.dataloop;			break;		    case DLOOP_KIND_STRUCT:			load_dlp = DLOOP_STACKELM_STRUCT_DATALOOP(cur_elmp,								  count_index);			break;		    default:			/* --BEGIN ERROR HANDLING-- */			DLOOP_Assert(0);			break;			/* --END ERROR HANDLING-- */		}#ifdef DLOOP_DEBUG_MANIPULATE		DLOOP_dbg_printf("\tloading dlp=%x, elmp=%x [%d]\n",				 (unsigned) load_dlp,				 (unsigned) next_elmp,				 cur_sp+1);#endif		DLOOP_Stackelm_load(next_elmp,				    load_dlp,				    1);	    }#ifdef DLOOP_DEBUG_MANIPULATE	    DLOOP_dbg_printf("\tpushing type, elmp=%x [%d], count=%d, block=%d\n",			    (unsigned) cur_elmp, cur_sp, count_index,			     block_index);#endif	    /* set orig_offset and all cur values for new stackelm.	     * this is done in two steps: first set orig_offset based on	     * current stackelm, then set cur values based on new stackelm.	     */	    switch (cur_elmp->loop_p->kind & DLOOP_KIND_MASK) {		case DLOOP_KIND_CONTIG:		    next_elmp->orig_offset = cur_elmp->curoffset +			block_index * cur_elmp->loop_p->el_extent;		    break;		case DLOOP_KIND_VECTOR:		    /* note: stride is in bytes */		    next_elmp->orig_offset = cur_elmp->orig_offset +			count_index * cur_elmp->loop_p->loop_params.v_t.stride +			block_index * cur_elmp->loop_p->el_extent;		    break;		case DLOOP_KIND_BLOCKINDEXED:		    next_elmp->orig_offset = cur_elmp->orig_offset +			block_index * cur_elmp->loop_p->el_extent +			DLOOP_STACKELM_BLOCKINDEXED_OFFSET(cur_elmp,							   count_index);		    break;		case DLOOP_KIND_INDEXED:		    next_elmp->orig_offset = cur_elmp->orig_offset +			block_index * cur_elmp->loop_p->el_extent +			DLOOP_STACKELM_INDEXED_OFFSET(cur_elmp, count_index);		    break;		case DLOOP_KIND_STRUCT:		    next_elmp->orig_offset = cur_elmp->orig_offset +			block_index * DLOOP_STACKELM_STRUCT_EL_EXTENT(cur_elmp, count_index) +			DLOOP_STACKELM_STRUCT_OFFSET(cur_elmp, count_index);		    break;		default:		    /* --BEGIN ERROR HANDLING-- */		    DLOOP_Assert(0);		    break;		    /* --END ERROR HANDLING-- */	    }#ifdef DLOOP_DEBUG_MANIPULATE	    DLOOP_dbg_printf("\tstep 1: next orig_offset = %d (0x%x)\n",			     next_elmp->orig_offset,			     next_elmp->orig_offset);#endif	    switch (next_elmp->loop_p->kind & DLOOP_KIND_MASK) {		case DLOOP_KIND_CONTIG:		case DLOOP_KIND_VECTOR:		    next_elmp->curcount  = next_elmp->orig_count;		    next_elmp->curblock  = next_elmp->orig_block;		    next_elmp->curoffset = next_elmp->orig_offset;		    break;		case DLOOP_KIND_BLOCKINDEXED:		    next_elmp->curcount  = next_elmp->orig_count;		    next_elmp->curblock  = next_elmp->orig_block;		    next_elmp->curoffset = next_elmp->orig_offset +			DLOOP_STACKELM_BLOCKINDEXED_OFFSET(next_elmp, 0);		    break;		case DLOOP_KIND_INDEXED:		    next_elmp->curcount  = next_elmp->orig_count;		    next_elmp->curblock  =			DLOOP_STACKELM_INDEXED_BLOCKSIZE(next_elmp, 0);		    next_elmp->curoffset = next_elmp->orig_offset +			DLOOP_STACKELM_INDEXED_OFFSET(next_elmp, 0);		    break;		case DLOOP_KIND_STRUCT:		    next_elmp->curcount = next_elmp->orig_count;		    next_elmp->curblock =			DLOOP_STACKELM_STRUCT_BLOCKSIZE(next_elmp, 0);		    next_elmp->curoffset = next_elmp->orig_offset +			DLOOP_STACKELM_STRUCT_OFFSET(next_elmp, 0);		    break;		default:		    /* --BEGIN ERROR HANDLING-- */		    DLOOP_Assert(0);		    break;		    /* --END ERROR HANDLING-- */	    }#ifdef DLOOP_DEBUG_MANIPULATE	    DLOOP_dbg_printf("\tstep 2: next curoffset = %d (0x%x)\n",			     next_elmp->curoffset,			     next_elmp->curoffset);#endif	    cur_elmp->curblock--;	    DLOOP_SEGMENT_PUSH;	} /* end of else push the stackelm */    } /* end of for (;;) */#ifdef DLOOP_DEBUG_MANIPULATE    DLOOP_dbg_printf("hit end of datatype\n");#endif    DLOOP_SEGMENT_SAVE_LOCAL_VALUES;    return;}/* DLOOP_Stackelm_blocksize - returns block size for stackelm based on current * count in stackelm. * * NOTE: loop_p, orig_count, and curcount members of stackelm MUST be correct * before this is called! * */static inline DLOOP_Count DLOOP_Stackelm_blocksize(struct DLOOP_Dataloop_stackelm *elmp){    struct DLOOP_Dataloop *dlp = elmp->loop_p;           switch(dlp->kind & DLOOP_KIND_MASK) {	case DLOOP_KIND_CONTIG:	    /* NOTE: we're dropping the count into the	     * blksize field for contigs, as described	     * in the init call.	     */	    return dlp->loop_params.c_t.count;	    break;	case DLOOP_KIND_VECTOR:	    return dlp->loop_params.v_t.blocksize;	    break;	case DLOOP_KIND_BLOCKINDEXED:	    return dlp->loop_params.bi_t.blocksize;	    break;	case DLOOP_KIND_INDEXED:	    return dlp->loop_params.i_t.blocksize_array[elmp->orig_count - elmp->curcount];	    break;	case DLOOP_KIND_STRUCT:	    return dlp->loop_params.s_t.blocksize_array[elmp->orig_count - elmp->curcount];	    break;	default:	    /* --BEGIN ERROR HANDLING-- */	    DLOOP_Assert(0);	    break;	    /* --END ERROR HANDLING-- */    }    return -1;}/* DLOOP_Stackelm_offset - returns starting offset (displacement) for stackelm * based on current count in stackelm. * * NOTE: loop_p, orig_count, and curcount members of stackelm MUST be correct * before this is called! * * also, this really is only good at init time for vectors and contigs  * (all the time for indexed) at the moment. * */static inline DLOOP_Offset DLOOP_Stackelm_offset(struct DLOOP_Dataloop_stackelm *elmp){    struct DLOOP_Dataloop *dlp = elmp->loop_p;           switch(dlp->kind & DLOOP_KIND_MASK) {	case DLOOP_KIND_VECTOR:	case DLOOP_KIND_CONTIG:	    return 0;	    break;	case DLOOP_KIND_BLOCKINDEXED:	    return dlp->loop_params.bi_t.offset_array[elmp->orig_count - elmp->curcount];	    break;	case DLOOP_KIND_INDEXED:	    return dlp->loop_params.i_t.offset_array[elmp->orig_count - elmp->curcount];	    break;	case DLOOP_KIND_STRUCT:	    return dlp->loop_params.s_t.offset_array[elmp->orig_count - elmp->curcount];	    break;	default:	    /* --BEGIN ERROR HANDLING-- */	    DLOOP_Assert(0);	    break;	    /* --END ERROR HANDLING-- */    }    return -1;}/* DLOOP_Stackelm_load * loop_p, orig_count, orig_block, and curcount are all filled by us now. * the rest are filled in at processing time. */static inline void DLOOP_Stackelm_load(struct DLOOP_Dataloop_stackelm *elmp,				       struct DLOOP_Dataloop *dlp,				       int branch_flag){    elmp->loop_p = dlp;    if ((dlp->kind & DLOOP_KIND_MASK) == DLOOP_KIND_CONTIG) {	elmp->orig_count = 1; /* put in blocksize instead */    }    else {	elmp->orig_count = dlp->loop_params.count;    }    if (branch_flag || (dlp->kind & DLOOP_KIND_MASK) == DLOOP_KIND_STRUCT)    {	elmp->may_require_reloading = 1;    }    else {	elmp->may_require_reloading = 0;    }    /* required by DLOOP_Stackelm_blocksize */    elmp->curcount = elmp->orig_count;    elmp->orig_block = DLOOP_Stackelm_blocksize(elmp);    /* TODO: GO AHEAD AND FILL IN CURBLOCK? */}/*  * Local variables: * c-indent-tabs-mode: nil * End: */

⌨️ 快捷键说明

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