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

📄 grouputil.c

📁 刚才是说明 现在是安装程序在 LINUX环境下进行编程的MPICH安装文件
💻 C
字号:
/* -*- Mode: C; c-basic-offset:4 ; -*- *//* *  (C) 2001 by Argonne National Laboratory. *      See COPYRIGHT in top-level directory. */#include "mpiimpl.h"#include "group.h"#ifndef MPID_GROUP_PREALLOC #define MPID_GROUP_PREALLOC 8#endif/* Preallocated group objects */MPID_Group MPID_Group_builtin[MPID_GROUP_N_BUILTIN] = {    { MPI_GROUP_EMPTY, 1, 0, MPI_UNDEFINED, -1, 0, } };MPID_Group MPID_Group_direct[MPID_GROUP_PREALLOC];MPIU_Object_alloc_t MPID_Group_mem = { 0, 0, 0, 0, MPID_GROUP, 				      sizeof(MPID_Group), MPID_Group_direct,				       MPID_GROUP_PREALLOC};/*  * Allocate a new group and the group lrank to lpid array.  Does *not*  * initialize any arrays, but does set the reference count. */int MPIR_Group_create( int nproc, MPID_Group **new_group_ptr ){    int mpi_errno = MPI_SUCCESS;    *new_group_ptr = (MPID_Group *)MPIU_Handle_obj_alloc( &MPID_Group_mem );    if (!*new_group_ptr) {	mpi_errno = MPIR_Err_create_code( MPI_ERR_OTHER, "**nomem", 0 );	return mpi_errno;    }    /* printf( "new group ptr is %x handle %x\n", (int)*new_group_ptr,       (*new_group_ptr)->handle );fflush(stdout); */    MPIU_Object_set_ref( *new_group_ptr, 1 );    (*new_group_ptr)->lrank_to_lpid = 	(MPID_Group_pmap_t *)MPIU_Malloc( nproc * sizeof(MPID_Group_pmap_t) );    if (!(*new_group_ptr)->lrank_to_lpid) {	MPIU_Handle_obj_free( &MPID_Group_mem, *new_group_ptr );	*new_group_ptr = NULL;	mpi_errno = MPIR_Err_create_code( MPI_ERR_OTHER, "**nomem", 0 );	return mpi_errno;    }    (*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;    return mpi_errno;}/* * return value is the first index in the list * * This sorts an lpid array by lpid value, using a simple merge sort * algorithm. * */static int MPIR_Mergesort_lpidarray( MPID_Group_pmap_t maparray[], int n ){    int idx1, idx2, first_idx, cur_idx, next_lpid, idx2_offset;    if (n == 2) {	if (maparray[0].lpid > maparray[1].lpid) {	    first_idx = 1;	    maparray[0].next_lpid = -1;	    maparray[1].next_lpid = 0;	}	else {	    first_idx = 0;	    maparray[0].next_lpid = 1;	    maparray[1].next_lpid = -1;	}	return first_idx;    }    if (n == 1) {	maparray[0].next_lpid = -1;	return 0;    }    if (n == 0) 	return -1;    /* Sort each half */    idx2_offset = n/2;    idx1 = MPIR_Mergesort_lpidarray( maparray, n/2 );    idx2 = MPIR_Mergesort_lpidarray( maparray + idx2_offset, n - n/2 ) + idx2_offset;    /* merge the results */    /* There are three lists:       first_idx - points to the HEAD of the sorted, merged list       cur_idx - points to the LAST element of the sorted, merged list       idx1    - points to the HEAD of one sorted list       idx2    - points to the HEAD of the other sorted list              We first identify the head element of the sorted list.  We then        take elements from the remaining lists.  When one list is empty,       we add the other list to the end of sorted list.        The last wrinkle is that the next_lpid fields in maparray[idx2]       are relative to n/2, not 0 (that is, a next_lpid of 1 is       really 1 + n/2, relative to the beginning of maparray).    */    /* Find the head element */    if (maparray[idx1].lpid > maparray[idx2].lpid) {	first_idx = idx2;	idx2      = maparray[idx2].next_lpid + idx2_offset;    }    else {	first_idx = idx1;	idx1      = maparray[idx1].next_lpid;    }        /* Merge the lists until one is empty */    cur_idx = first_idx;    while ( idx1 >= 0 && idx2 >= 0) {	if (maparray[idx1].lpid > maparray[idx2].lpid) {	    next_lpid			= maparray[idx2].next_lpid;	    if (next_lpid >= 0) next_lpid += idx2_offset;	    maparray[cur_idx].next_lpid	= idx2;	    cur_idx			= idx2;	    idx2			= next_lpid;	}	else {	    next_lpid			= maparray[idx1].next_lpid;	    maparray[cur_idx].next_lpid	= idx1;	    cur_idx			= idx1;	    idx1			= next_lpid;	}    }    /* Add whichever list remains */    if (idx1 >= 0) {	maparray[cur_idx].next_lpid = idx1;    }    else {	maparray[cur_idx].next_lpid = idx2;	/* Convert the rest of these next_lpid values to be 	   relative to the beginning of maparray */	while (idx2 >= 0) {	    next_lpid = maparray[idx2].next_lpid;	    if (next_lpid >= 0) {		next_lpid += idx2_offset;		maparray[idx2].next_lpid = next_lpid;	    }	    idx2 = next_lpid;	}    }    return first_idx;}/*  * Create a list of the lpids, in lpid order. */void MPIR_Group_setup_lpid_list( MPID_Group *group_ptr ){    /* Lock around the data structure updates in case another thread       decides to update the same group.  Note that this is needed only       for MPI_THREAD_MULTIPLE */    MPID_Common_thread_lock();    {	if (group_ptr->idx_of_first_lpid == -1) {	    group_ptr->idx_of_first_lpid = 		MPIR_Mergesort_lpidarray( group_ptr->lrank_to_lpid, 					  group_ptr->size );	}    }    MPID_Common_thread_unlock();    return;}void MPIR_Group_setup_lpid_pairs( MPID_Group *group_ptr1, 				  MPID_Group *group_ptr2 ){    /* If the lpid list hasn't been created, do it now */    if (group_ptr1->idx_of_first_lpid < 0) { 	MPIR_Group_setup_lpid_list( group_ptr1 );     }    if (group_ptr2->idx_of_first_lpid < 0) { 	MPIR_Group_setup_lpid_list( group_ptr2 );     }}#ifdef HAVE_ERROR_CHECKING/*  * The following routines are needed only for error checking *//* * This routine is for error checking for a valid ranks array, used * by Group_incl and Group_excl */int MPIR_Group_check_valid_ranks( MPID_Group *group_ptr, int ranks[], int n ){    int mpi_errno = MPI_SUCCESS, i;    /* Thread lock in case any other thread wants to use the group       data structure.  Needed only for MPI_THREAD_MULTIPLE */    if (n < 0) {	mpi_errno = MPIR_Err_create_code( MPI_ERR_ARG, "**argneg",					  "**argneg %s %d", "n", n );	return mpi_errno;    }    MPID_Common_thread_lock();    {	for (i=0; i<group_ptr->size; i++) {	    group_ptr->lrank_to_lpid[i].flag = 0;	}	for (i=0; i<n; i++) {	    if (ranks[i] < 0 ||		ranks[i] >= group_ptr->size) {		mpi_errno = MPIR_Err_create_code( MPI_ERR_RANK,				  "**rankarray", "**rankarray %d %d %d",				  i, ranks[i], group_ptr->size );		break;	    }	    if (group_ptr->lrank_to_lpid[ranks[i]].flag) {		mpi_errno = MPIR_Err_create_code( MPI_ERR_RANK,				"**rankdup", "**rankdup %d %d %d",				  i, ranks[i], 				  group_ptr->lrank_to_lpid[ranks[i]].flag-1);		break;	    }	    group_ptr->lrank_to_lpid[ranks[i]].flag = i+1;	}    }    MPID_Common_thread_unlock();    return mpi_errno;}int MPIR_Group_check_valid_ranges( MPID_Group *group_ptr, 				   int ranges[][3], int n ){    int i, j, size, first, last, stride, mpi_errno = MPI_SUCCESS;    if (n < 0) {	mpi_errno = MPIR_Err_create_code( MPI_ERR_ARG, "**argneg",					  "**argneg %s %d", "n", n );	return mpi_errno;    }    /* Lock in case another thread is accessing the group        data structures */    MPID_Common_thread_lock();    size = group_ptr->size;        /* First, clear the flag */    for (i=0; i<size; i++) {	group_ptr->lrank_to_lpid[i].flag = 0;    }    for (i=0; i<n; i++) {	first = ranges[i][0]; last = ranges[i][1]; 	stride = ranges[i][2];	if (first < 0 || first >= size) {	    mpi_errno = MPIR_Err_create_code( MPI_ERR_ARG,					      "**rangestartinvalid", 					      "**rangestartinvalid %d %d %d", 					      i, first, size );	    break;	}	if (last < 0 || last >= size) {	    mpi_errno = MPIR_Err_create_code( MPI_ERR_ARG,					      "**rangeendinvalid", 					      "**rangeendinvalid %d %d %d", 					      i, last, size );	    break;	}	if (stride != 0) {	    if ( (stride > 0 && first > last) ||		 (stride < 0 && first < last) ) {		mpi_errno = MPIR_Err_create_code( MPI_ERR_ARG, 						  "**stride", "**stride %d %d %d", 						  first, last, stride );		break;	    }	}	else {	    mpi_errno = MPIR_Err_create_code( MPI_ERR_ARG, 					      "**stridezero", 0 );	    break;	}	/* range is valid.  Mark flags */	if (stride > 0) {	    for (j=first; j<=last; j+=stride) {		if (group_ptr->lrank_to_lpid[j].flag) {		    mpi_errno = MPIR_Err_create_code( MPI_ERR_ARG,						      "**rangedup", 				    "**rangedup %d %d %d",				    j, i, group_ptr->lrank_to_lpid[j].flag - 1);		    break;		}		else		    group_ptr->lrank_to_lpid[j].flag = 1;	    }	}	else {	    for (j=first; j>=last; j+=stride) {		if (group_ptr->lrank_to_lpid[j].flag) {		    mpi_errno = MPIR_Err_create_code( MPI_ERR_ARG,						      "**rangedup", 				    "**rangedup %d %d %d",				    j, i, group_ptr->lrank_to_lpid[j].flag - 1);		    break;		}		else		    /* Set to i + 1 so that we can remember where it was 		       first set */		    group_ptr->lrank_to_lpid[j].flag = i + 1;	    }	}	if (mpi_errno) break;    }    MPID_Common_thread_unlock();    return mpi_errno;}#endif  /* HAVE_ERROR_CHECKING */

⌨️ 快捷键说明

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